This is My model class. I am trying to get an http response and print it to my app.
At line 12 DataModel it's showing me this error
"Non-nullable instance field 'buttonStartingYpoint' must be initialized.
Try adding an initializer expression, or add a field initializer in this constructor, or mark it 'late'."
Non-nullable instance field 'buttonHeight' must be initialized.
Try adding an initializer expression, or add a field initializer in this constructor, or mark it 'late'
String buttonLetter;
int buttonHeight;
int buttonWidth;
int buttonStartingXpoint;
int buttonStartingYpoint;
DataModel(
{required this.buttonLetter,
required this.buttonHeight,
required this.buttonWidth,
required this.buttonStartingXpoint,
required this.buttonStartingYpoint});
DataModel.fromJson(Map<String, dynamic> json) {
buttonLetter = json['Button_letter'];
buttonHeight = json['Button_height'];
buttonWidth = json['Button_width'];
buttonStartingXpoint = json['Button_Starting_xpoint'];
buttonStartingYpoint = json['Button_Starting_ypoint'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['Button_letter'] = this.buttonLetter;
data['Button_height'] = this.buttonHeight;
data['Button_width'] = this.buttonWidth;
data['Button_Starting_xpoint'] = this.buttonStartingXpoint;
data['Button_Starting_ypoint'] = this.buttonStartingYpoint;
return data;
}
}
I tried to add late but then its showing error in both late and model. And I am new to flutter
You have to initialize them in the initializer list. When you get to the constructor body it's too late. Here's the fix:
DataModel.fromJson(Map<String, dynamic> json) :
buttonLetter: json['Button_letter'],
buttonHeight: json['Button_height'],
buttonWidth: json['Button_width'],
buttonStartingXpoint: json['Button_Starting_xpoint'],
buttonStartingYpoint: json['Button_Starting_ypoint'];
For reference: https://dart.dev/guides/language/language-tour#constructors
Related
I am getting following errors:
Instance members can't be accessed from a factory constructor. (Documentation) Try removing the reference to the instance member.
The argument type 'List<Map<String, dynamic>>?' can't be assigned to the parameter type 'List<Vaccination>'. (Documentation)
at line _convertVaccinations(json['vaccinations'] as List<dynamic>));
Code:
final String name;
final String? notes;
final String type;
final List<Vaccination> vaccination;
final String? referenceId;
Pet(this.name, {this.notes, required this.type, required this.vaccination, this.referenceId});
factory Pet.fromJson(Map<String, dynamic> json) =>
Pet(
json['name'] as String,
notes: json['notes'] as String,
type: json['types'] as String,
referenceId: json['referenceId'] as String,
vaccination:
_convertVaccinations(json['vaccinations'] as List<dynamic>));
List<Map<String, dynamic>>? _convertVaccinations(List<dynamic>? vaccinations) {
if (vaccinations == null) {
return null;
} else {
final vaccinationMap = <Map<String, dynamic>>[];
for (var element in vaccinations) {
vaccinationMap.add(element.toJson);
}
return vaccinationMap;
}
}
Factory and instance member error:
Well it is because factory Pet.fromJson(...) is a factory constructor, and the class method _convertVaccinations(...) is an instance member.
If you make _convertVaccinations(...) static, it will accept the use of it in the factory constructor.
Argument error:
vaccination is of type List<Vaccination> and the method _convertVaccination(...) returns either null or List<Map<String, dynamic>>
In other words, you cannot assign null to List<T> unless it says List<T>? and the class Vaccination is not a Map<String, dynamic>
Maybe you want to do something like final List<Vaccination>? vaccinations; OR return <Vaccination>[] instead of null if vaccinations == null.
So you'd probably want to do write _convertVaccinations(...) as:
static List<Vaccination>? _convertVaccination(List<dynamic>? vaccinations) {
return vaccinations?.map((e) => Vaccination.fromJson(e as Map<String,dynamic>).toList();
}
or:
static List<Vaccination> _convertVaccination(List<dynamic>? vaccinations) {
return vaccinations?.map((e) => Vaccination.fromJson(e as Map<String,dynamic>).toList() ?? <Vaccination>[];
}
Side note: Maybe you have more methods that you haven't presented here. Because it looks a bit wonky when your Pet.fromJson(...) use a element.toJson down the call stack.
I have a class with non-nullable values whose default values I have defined in the constructor.
class AirConPreferences {
bool allowOn;
int lowerTemperature;
int upperTemperature;
String nickName;
AirConPreferences({
this.allowOn = false,
this.lowerTemperature = 19,
this.upperTemperature = 24,
this.nickName = "",
});
factory AirConPreferences.fromJson(Map<String, dynamic> json) =>
AirConPreferences(
allowOn: json['allowOn'],
lowerTemperature: json['lowerTemperature'],
upperTemperature: json['upperTemperature'],
nickName: json['nickName'],
);
Map<String, dynamic> toJson() => {
"allowOn": allowOn,
"lowerTemperature": lowerTemperature,
"upperTemperature": upperTemperature,
"nickName": nickName,
};
}
In my API call, I sometimes don't get all the values so some of the values could be null. Instead of taking the default value defined in the constructor, it's giving the following error:
AirConPreferences preferences = AirConPreferences.fromJson({});
Uncaught Error: TypeError: null: type 'JSNull' is not a subtype of type 'bool'
The first check did you decode the JSON when you send the data into the fromJson method perimeter.
Then use the null check operator and set the default value. as like. ,
allowOn: json['allowOn']?? false
You can do the following
AirConPreferences({
final bool? allowOn,
final int? lowerTemperature,
final int? upperTemperature,
final Stirng? nickName,
}) : this.allowOn = allowOn ?? false,
this.lowerTemperature = lowerTemperature ?? 19,
this.upperTemperature = upperTemperature ?? 24,
this.nickName = nickName ?? "";
This will solve the issue, in case you will have multiple factories, you don't have to override them for all of them
I am new to Flutter.
I am creating a named constructor to work with flutter Models. But for some reason it is showing an error:
class ImageModel {
int id;
String url;
String title;
// constructor
ImageModel(this.id, this.url, this.title);
// named constructor
ImageModel.fromJSON(Map<String, dynamic> parsedJson) {
id = parsedJson['id'];
url = parsedJson['url'];
title = parsedJson['title'];
}
}
Error:
Non-nullable instance field 'url' must be initialized.
Try adding an initializer expression, or add a field initializer
in this constructor, or mark it 'late'.dartnot_initialized_non_nullable_instance_field
I read the documentation, and found this solution, not sure why this is required at this place. I know its use case, but should not this work without this ?
class ImageModel {
late int id; // refactor
late String url; // refactor
late String title; // refactor
.
.
.
You have used incorrect syntax for the named constructor.
Instead of
ImageModel.fromJSON(Map<String, dynamic> parsedJson) {
id = parsedJson['id'];
url = parsedJson['url'];
title = parsedJson['title'];
}
it must be
ImageModel.fromJSON(Map<String, dynamic> parsedJson) :
id = parsedJson['id'],
url = parsedJson['url'],
title = parsedJson['title'];
The object is initialized after colon(:) in named constructor and curly brackets({}) are then used if you want to perform some task after initialization of object. Since you directly used {} after named constructor, it created an empty object for you and hence all parameters were null which you were trying to initialize in the function body. That's why this issue was solved after using 'late' keyword.
do you like this way
factory ImageModel.fromJson(Map<String, dynamic> json) {
return ImageModel(
json["id"],
json["url"],
json["title"],
);
}
And i prefer
class ImageModel {
int id;
String url;
String title;
// constructor
ImageModel({
required this.id,
required this.url,
required this.title,
});
factory ImageModel.fromJson(Map<String, dynamic> json) {
return ImageModel(
id: json["id"],
url: json["url"],
title: json["title"],
);
}
}
The Dart compiler complains because of its "null safety" feature. This means, that variable types like int or String must be initialised. This is been checked for at compile time. You can either add required in the constructor
ImageModel({
required this.id,
required this.url,
required this.title,
});
so that you cannot call the constructor without initialising the fields or let the compiler know that you will take care of the initialisation later by adding the late keyword (as you did). Of course you can also initialise the variables with some default values, if there are such
int id = 0;
String url = "https://www.example.com/default.jpg";
String title = "Default Text";
but that seems to be more of a corner case.
My error:
type '_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'Food' in type cast
I get the list from the server, using fromJson I get it in the format I need
this class contains another list of another class and I can't interact with it. when I try to pull something from the built-in list, I get an error, and the list is displayed as CastList
my class:
class FoodGroup{
#PrimaryKey()
int id;
String name;
List<Food> foods;
FoodGroup({this.name,
this.id,
this.foods});
FoodGroup.map(dynamic obj) {
this.id = obj["id"];
this.foods = obj["foods"].cast<Food>();
this.name = obj["name"];
}
Map<String, dynamic> toMap() {
var map = new Map<String, dynamic>();
map["id"] = id;
map["foods"] = foods;
map["name"] = name;
return map;
}
FoodGroup.fromJson(Map<String, dynamic> json)
: id = json['id'],
foods = json['foods'].cast<Food>(),
name = json['name'];
}
. cast() I need to decode from json:
var l = jsonDecode(r.body) as List;
foodTable = l.map((i) => FoodGroup.fromJson(i)).toList();
with FoodGroup everything is ok, the problem is in List
I used json annotation and autogeneration code, this solved the problems with deserializing the nested list, but the number of files in the project has increased significantly, not very nice
I am setting up my model classes to confirm to the docs for sqflite which suggest including a named constructor to convert to/from Maps to better handling of data between the classes and the DB. Every example I can find is very simple, with class properties all being simple data types.
Using the constructor and method shown below, converting to/from Map is quite simple when dealing with a class such as this.
class Human{
final String name;
final String height;
Final String weight;
Human({this.name, this.height, this.weight});
}
However, when you have a class where one of the fields is a bit more complex, I do not understand how to structure things within the named constructor and xxx method to return the map of data that I 'believe' I should get.
class Human{
final String name;
final String height;
Final String weight;
List<Child> children = [];
Human({this.name, this.height, this.weight, this.children});
}
Human({this.name, this.height, this.weight, this.children});
Human.fromMap(Map<String, dynamic> map)
: name = map['name'],
height = map['height'],
weight = map['weight'],
children = map['children'];
Map<String, dynamic> toMap() {
return {
'name': name,
'height': height,
'weight': weight,
'children': children,
};
}
The List children is the part I am struggling with. I believe you have to get each Child object ALSO converted to a map within the parent map, but am losing the battle here.
Is my approach way off here? Is there some other method I should be using to accomplish this?
Any assistance would be much appreciated.
Here I am explaining the following
How to convert a model object into Map to use with sqlite
How to convert a Map object from sqlite into a model class.
How to parse JSON reponse properly in flutter
How to convert a model object into JSON
All of the above questions has same answer. Dart has great support for these operations. Here I am going to illustrate it with a detailed example.
class DoctorList{
final List<Doctor> doctorList;
DoctorList({this.doctorList});
factory DoctorList.fromMap(Map<String, dynamic> json) {
return DoctorList(
doctorList: json['doctorList'] != null
? (json['doctorList'] as List).map((i) => Doctor.fromJson(i)).toList()
: null,
);
}
Map<String, dynamic> toMap() {
final Map<String, dynamic> data = Map<String, dynamic>();
if (this.doctorList != null) {
data['doctorList'] = this.doctorList.map((v) => v.toMap()).toList();
}
return data;
}
}
The above DoctorList class has a member which holds a list of 'Doctor' objects..
And see how I parsed the doctorList.
doctorList: json['doctorList'] != null
? (json['doctorList'] as List).map((i) => Doctor.fromMap(i)).toList()
: null,
You may wonder, how the Doctor class may look like. Here you go
class Doctor {
final String doCode;
final String doctorName;
Doctor({this.doCode, this.doctorName});
factory Doctor.fromMap(Map<String, dynamic> json) {
return Doctor(
doCode: json['doCode'],
doctorName: json['doctorName'],
);
}
Map<String, dynamic> toMap() {
final Map<String, dynamic> data = Map<String, dynamic>();
data['doCode'] = this.doCode;
data['doctorName'] = this.doctorName;
return data;
}
}
That's all. Hope you got the idea. Cheers!