I am using banklist in stateful widget. passing list to pageState using List<Bank> bankLists = this.widget.bankLists;
Que 1. Why I am getting error at gradientcolor: gradientBankCard("FFB74093","FFB74093")) that only static members can be accessed in initializer?
Que 2. How to pass const Data to gradientBankCard method . for Example I want to pass Color.fromRGBO(220, 132, 58, 1.0) to Arguments that gives error to.
I
List<Bank> bankLists = [
Bank(
id: "1",
name: "B1",
loanAmount: "₹ 250000",
emi: "₹11732",
intrest_rate: "11.69 % ",
processing_fee: "1.29 %",
tenure: "2 years",
gradientcolor: gradientBankCard('#e48634', '#e48634')), // //Error : Only static members can be accessed in initializers
Bank(
id: "2",
name: "B2",
loanAmount: "₹ 250000",
emi: "₹11732",
intrest_rate: "11.69 % ",
processing_fee: "1.29 %",
tenure: "2 years",
gradientcolor: gradientBankCard('#e48634', '#e48634')) //Error : Only static members can be accessed in initializers
];
Now I am using in my listing screen .
LinearGradient gradientBankCard(String startColor, String endColor){
return LinearGradient(
begin: Alignment.topLeft,
end: Alignment.bottomRight,
colors: [Color(hexToInt(startColor)),Color(hexToInt(endColor))]
);
}
Bank Model.dart
import 'package:flutter/material.dart';
class Bank {
final String id;
final String name;
final String loanAmount;
final String emi;
final String intrest_rate;
final String processing_fee;
final String tenure;
LinearGradient gradientcolor;
Bank({this.id, this.name, this.loanAmount, this.emi, this.intrest_rate,
this.processing_fee, this.tenure,this.gradientcolor});
}
The code
gradientcolor: gradientBankCard('#e48634', '#e48634')),
is executed before the class is fully initialized.
Initializers of fields like
List<Bank> bankLists = [...];
is executed before the super constructors are executed and at that point explicit or implict access to this. is not allowed because it would allow access to incompletely initialized state.
If you change
LinearGradient gradientBankCard(String startColor, String endColor){ ...
to
static LinearGradient gradientBankCard(String startColor, String endColor){
then there is no way to access this. and is therefore safe.
Related
I'm new to model writing and I need your help.
I write a code like this:
import 'dart:js';
import 'dart:math';
List AllWords = [{"ID": 0, "Word": "This is words.", "Author": "Emir"}, {"ID": 1, "Word": "This is words.", "Author": "Jack"}];
class Words {
final int ID;
final String Word;
final String Author;
Words(this.ID, this.Word, this.Author);
void GetWords() {
final _random = new Random();
var Words = AllWords[_random.nextInt(AllWords.length)];
return Words;
}
}
My goal is to fetch a random word from the list when I use the GetWords Function. Is this code correct? How can I use this code I wrote in main.dart?
Thanks for help.
try this :
import 'dart:math' as math;
//your list is a map, not a `Words` class
//if your list is a `Words` class, it will be like this :
//final allWords = [Words(Id,words,author), Words()}
List<Map<String, Object?>> allWords = [
{"ID": 0, "Word": "This is words.", "Author": "Emir"},
{"ID": 1, "Word": "This is words.", "Author": "Jack"}
];
class Words {
final int iD;
final String word;
final String author;
Words({required this.iD, required this.author, required this.word});
factory Words.fromJson(Map<String, Object?> json) {
return Words(
iD: json['ID'] as int,
author: json['Author'] as String,
word: json['Word'] as String);
}
factory Words.getRandomWord() {
math.Random random = math.Random();
return Words.fromJson(allWords[random.nextInt(allWords.length - 1)]);
}
}
//Somewhere else in your code
Words myWord = Words.getRandomWord();
I have code like this
class Human<T> { // <--- this is the superclass
final String name;
final T belongings;
Human({
required this.name,
required this.belongings,
});
}
class Athlete<T> extends Human { // <--- this is the subclass
final String sportType;
Athlete({
required String name,
required belongings,
required this.sportType,
}) : super(name: name, belongings: belongings);
}
final messi = Athlete<List<String>>( // <--- past List<String> as generic
name: "Lionel Messi",
belongings: ["Jersey", "Shoes"],
sportType: "Football",
);
final belonging = messi.belongings; // <-- the data type is dynamic, not List<String>
as you can see, I want belongings property to be generic, but after I pass List<String> as a generic type when instantiating an Athlete model, I still get dynamic data type like the image below, I expect it will be List<String> .
You need to add the <T> to Human, so it's extends Human<T>.
You also need to type the required belongings, parameter, either as
required T belongings,, or by using the new super-parameters feature and make it required super.belongings.
That is:
class Human<T> {
final String name;
final T belongings;
Human({
required this.name,
required this.belongings,
});
}
class Athlete<T> extends Human<T> { // <--- added <T>
final String sportType;
Athlete({
required super.name, // <--- used super.name
required super.belongings, // <--- used super.longings
required this.sportType,
}); // <--- no constructor call needed when it's all "super." parameters.
}
final messi = Athlete<List<String>>(
name: "Lionel Messi",
belongings: ["Jersey", "Shoes"],
sportType: "Football",
);
you have to declare belongings as a List within the human class like this:
final List<String> belongings;
Human({required this.belongings})
I have a device class in my application where one property needs to be computed and final plus some properties that can be set in the constructor or have default values. Here's the code:
class Device {
String idx;
String id;
String name;
String icon;
int order;
// have to create the idx before initializing the object because I can't
// figure out how to do that here.
Device(
{required this.idx,
required this.id,
required this.name,
this.icon = 'none',
this.order = -1});
// Creates a device from a JSON string
factory Device.fromJson(Map<String, dynamic> jsonData) {
return Device(
idx: jsonData['idx'],
id: jsonData['id'],
name: jsonData['name'],
icon: jsonData['icon'],
order: jsonData['order']);
}
// Returns the device as a String
static Map<String, dynamic> toMap(Device device) => {
'idx': device.idx,
'id': device.id,
'name': device.name,
'icon': device.icon,
'order': device.order
};
}
Basically I'm trying to set a unique index for the object so in my object list I can clearly identify a specific device. I'm using the Uuid package to generate a UUID for idx.
The only way I can make this work today is to create the idx in my other code that creates the object and pass it in. I read a lot of articles here that talk about different ways to solve this problem and I know I have to make the idx value a constant but I can't figure out how to do that and call the Uuid library.
I know it would look something like this:
Device(
{this.idx = const <<some calculation/expression>>,
required this.id,
required this.name,
this.icon = 'none',
this.order = -1});
removing the required modifier and putting a const before the value assignment. Nothing I've tried lets me call the Uuid method. Can someone help me understand how to do this?
Updating the code based on the answer from #jamesdlin:
import 'package:uuid/uuid.dart';
const uuid = Uuid();
class Device {
String idx;
String id;
String name;
String icon;
int order;
Device(
{String? idx,
required this.id,
required this.name,
this.icon = 'none',
this.order = -1})
: idx = idx ?? uuid.v1();
// Creates a device object from a JSON string
factory Device.fromJson(Map<String, dynamic> jsonData) {
return Device(
idx: jsonData['idx'],
id: jsonData['id'],
name: jsonData['name'],
icon: jsonData['icon'],
order: jsonData['order']);
}
// Returns the device object as a String
static Map<String, dynamic> toMap(Device device) => {
'idx': device.idx,
'id': device.id,
'name': device.name,
'icon': device.icon,
'order': device.order
};
}
This works, but I don't ever have a use case where I want the idx set manually, so how to I accomplish that? I could leave it like this, but I really want to better understand how to do exactly what I need.
The only way I can make this work today is to create the idx in my other code that creates the object and pass it in.
If you want the object to be able to generate its own UUID, you just can do:
const uuid = Uuid();
class Device {
String idx = uuid.v1(); // Or whatever UUID version you want.
...
or you if you want the caller to have the option to pass in a UUID string, you can use the typical technique of using null to achieve non-const default function arguments:
const uuid = Uuid();
class Device
String idx;
Device({String? idx, ...})
: idx = idx ?? uuid.v1(),
...
Note that attempting to make a const initializer for a UUID makes no sense. const means that the object is a compile-time constant, and furthermore, const objects are canonicalized, so a hypothetical const expression that generated a UUID would end up producing the same String for every Device, which would be the opposite of unique.
Update for you updated question
This works, but I don't ever have a use case where I want the idx set manually, so how to I accomplish that? I could leave it like this, but I really want to better understand how to do exactly what I need.
I don't understand what you mean since you quite obviously do have a use case for setting idx manually (your Device.fromJson factory constructor). If you instead mean that you don't have a use case for code from outside the Device class to manually set idx, then you can add a private constructor with the idx parameter and a public one without:
class Device {
String idx;
String id;
String name;
String icon;
int order;
Device({
required String id,
required String name,
String icon = 'none',
int order = -1,
}) : this._(
idx: uuid.v1(),
id: id,
name: name,
icon: icon,
order: order,
);
Device._({
required this.idx,
required this.id,
required this.name,
required this.icon,
required this.order,
});
// Creates a device object from a JSON string
factory Device.fromJson(Map<String, dynamic> jsonData) {
return Device._(
idx: jsonData['idx'],
id: jsonData['id'],
name: jsonData['name'],
icon: jsonData['icon'],
order: jsonData['order']);
}
}
or, since idx isn't final, .fromJson could assign it a value:
factory Device.fromJson(Map<String, dynamic> jsonData) {
return Device(
id: jsonData['id'],
name: jsonData['name'],
icon: jsonData['icon'],
order: jsonData['order'])
..idx = jsonData['idx'];
}
I've been trying to figure out how to use a named constructor to construct super and sub classes from JSON. Below is my example with some notes on what I've tried in the fromJson method body. Can anyone point me in the right direction? Thanks!
class Item {
final String name;
final int id;
final String image;
final double price;
final bool available;
Item(this.name, this.id, this.image, this.price, this.available);
Item.fromJson(Map<String, dynamic> json)
: name = json['name'],
id = json['id'],
image = json['image'],
price = json['price'],
available = json['available'];
}
class CartItem extends Item {
final int quantity;
CartItem({
#required this.quantity,
#required name,
#required id,
#required price,
#required image,
#required available
}): super(id, name, image, price, available)
CartItem.fromJson(Map<String, dynamic> json)
: quantity = json['quantity'],
// for whatever ever reason, super here seems to refer to CartItem
// so this doesn't work
super.name = json['name'],
// calling 'name' without the super doesn't work either
name = json['name']
}
You should use a the super's fromJson constructor in the child class's fromJson constructor. You can pass the Map in the child directly to the super without issues. Ex:
CartItem.fromJson(Map<String, dynamic> json)
: quantity = json['quantity'],
super.fromJson(json);
I created a const object at app.config.dart with the following code:
const configObj = const {
'webServer': const {
'appBaseHref' : "/"
},
'auth0': const {
'apiKey': "foo",
'domain': "bar",
'callbackUrl': "callback"
}
};
now in my main dart file I import the app.config.dart and I try to get the values there and now idea how to do that. configObj.auth0.apiKey produces the error EXCEPTION: Class 'ImmutableMap' has no instance getter 'auth0'.
so how do I do this ?
thanks!
Dart doesn't support to access map entries with .
It should be:
configObj['auth0']['apiKey'];
Alternatively you can create classes for your configuration like
class WebServerConfig {
final String appBaseHref;
const WebServerConfig(this.appBaseHref);
}
class Auth0Config {
final String apiKey;
final String domain;
final String callbackUrl;
const Auth0(this.apiKey, this.domain, this.callbackUrl);
}
class MyConfig {
final WebServerConfig webServer;
final Auth0Config auth0;
const MyConfig(this.webServer, this.auth0);
}
const configObj = const MyConfig(
const WebServerConfig("/"),
const Auth0Config(
"foo",
"bar",
"callback"
)
);
This way you also get proper auto-completion when you access the config properties and can use the simple . notation to access properties.