I am trying to convert a list of objects as a json string in shared preferences.
Object class
SuggestionModel suggestionModelFromJson(String str) =>
SuggestionModel.fromJson(json.decode(str));
String suggestionModelToJson(SuggestionModel data) =>
json.encode(data.toJson());
class SuggestionModel {
SuggestionModel({
this.category,
this.icon,
this.subs,
});
eCategory? category;
IconData? icon;
List<Sub>? subs;
factory SuggestionModel.fromJson(Map<String, dynamic> json) =>
SuggestionModel(
category: json["category"],
icon: json["icon"],
subs: List<Sub>.from(json["subs"].map((x) => Sub.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"category": category,
"icon": icon,
"subs": List<dynamic>.from(subs!.map((x) => x.toJson())),
};
}
class Sub {
Sub({
this.subCategory,
this.values,
});
String? subCategory;
List<Value>? values;
factory Sub.fromJson(Map<String, dynamic> json) => Sub(
subCategory: json["sub_category"],
values: List<Value>.from(json["values"].map((x) => Value.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"sub_category": subCategory,
"values": List<dynamic>.from(values!.map((x) => x.toJson())),
};
}
class Value {
Value({
this.subName,
this.selected,
});
String? subName;
bool? selected;
factory Value.fromJson(Map<String, dynamic> json) => Value(
subName: json["sub_name"],
selected: json["selected"],
);
Map<String, dynamic> toJson() => {
"sub_name": subName,
"selected": selected,
};
}
When I try to do
List<SuggestionModel> list;
String encodedData = jsonEncode(list);
it gives me an error
Converting object to an encodable object failed: Instance of 'SuggestionModel'
Im not following where the exact issue comes from. tried debugging and still no luck
How can I rectify this?
Update. I've changed the enum to a String and removed the IconData field. And the above issue had resolved.
Now when I try to get the saved Json string and convert that back to list of objects. I get an error
Unhandled Exception: type 'List<dynamic>' is not a subtype of type 'List<SuggestionModel>'
at this line
var t = await _dataManager.getSelectedList(s);
var addedObj = json.decode(json.decode(t!));
//here...
var list = addedObj.map((e) => SuggestionModel.fromJson(e)).toList();
Try this:
String encodedData = jsonEncode(list.map((e) => e.toJson()).toList());
So the first thing was to update the enum property of Model class to String and remove IconData.
Then for the second issue.
update the decoding function like
List<SuggestionModel> list =
addedObj.map((e) => SuggestionModel.fromJson(e)).toList();
Related
I try to get data from api. CallListDto class is empty according to user type. So, sometime this class is empty sometimes it has data. I populate dropdown menu items with this class.
My problem is, when this class is empty i got error. How can i solve this.
My model class is below
Login loginFromJson(String str) => Login.fromJson(json.decode(str));
String loginToJson(Login data) => json.encode(data.toJson());
class Login {
Login({
required this.token,
required this.callListDto,
});
String token;
List<CallListDto> callListDto;
factory Login.fromJson(Map<String, dynamic> json) => Login(
token: json["token"],
callListDto: List<CallListDto>.from(
json["callListDto"].map((x) => CallListDto.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"token": token,
"callListDto": List<dynamic>.from(callListDto.map((x) => x.toJson())),
};
}
class CallListDto {
CallListDto({
required this.callId,
required this.stationCode,
required this.callType,
});
int callId;
String stationCode;
int callType;
factory CallListDto.fromJson(Map<String, dynamic> json) => CallListDto(
callId: json["callID"],
stationCode: json["stationCode"],
callType: json["callType"],
);
Map<String, dynamic> toJson() => {
"callID": callId,
"stationCode": stationCode,
"callType": callType,
};
}
Before calling the model class check that str is not empty, for example
if (dataObject.isEmpty) return;
I used the fromJson method to recover a Struct with a List from Json decode http request and receiver it on my class, but now i want to do a reverse, i want to pass the data on my class to my toJson method and send him to a Json encode http POST. Please, i new on Dart/Flutter, someone know how to do this?
import 'dart:convert';
List<Itens> userFromJson(String str) =>
List<Itens>.from(jsonDecode(str).map((x) => Itens.fromJson(x)));
class Coletas {
final int codigo;
final String dataIni;
late String? dataFin;
late String? status;
final List<Itens> itemList;
Coletas(
{
required this.dataIni,
this.dataFin,
this.status,
required this.codigo,
required this.itemList
}
);
factory Coletas.fromJson(Map<String, dynamic> json) {
return Coletas(
dataIni: json['dtData'],
codigo: json['iCodigo'],
itemList: List<Itens>.from(json['stItens'].map((x) => Itens.fromJson(x))),
);
}
Map<String, dynamic> toMap() {
return {
'codigo': codigo,
'dataIni': dataIni,
'dataFin': dataFin,
'status': status
};
}
}
class Itens {
final int? id;
final int codigo;
late int quantidade;
late String? status;
final String codigoEAN;
Itens({
this.id,
this.status,
required this.codigo,
required this.codigoEAN,
required this.quantidade,
});
Map<String, dynamic> toJson(){
return {
'icodigo' : codigo,
'sCodigoBarras': codigoEAN,
'iQtd': quantidade
};
}
factory Itens.fromJson(Map<String, dynamic> json) {
return Itens(
codigo: json['iCodigo'],
codigoEAN: json['sCodigoBarras'],
quantidade: json['iQtd'],
);
}
Map<String, dynamic> toMap() {
return {
'id': id,
'status': status,
'codigo': codigo,
'codigoEAN': codigoEAN,
'quantidade': quantidade,
};
}
}
I tried to pass ever item on List separeted so, but not happen i expected.
Map<String, dynamic> toJSon(Coletas value) =>
{
'dtData' : dataIni,
'iCodigo': codigo,
'stItens': [],
};
For a better structure - format and use you can look at the flutter serialization documentation : https://docs.flutter.dev/development/data-and-backend/json.
It explains how to create your model and how to generate them to create fromJson and toJson Model based on the defined data. (https://docs.flutter.dev/development/data-and-backend/json#creating-model-classes-the-json_serializable-way)
It will helps you with your parsing - sending - receiving data.
I think you should assign Coletas as
Map<String, dynamic> toJSon(Coletas value) =>
{
'dtData' : value.dataIni,
'iCodigo': value.codigo,
'stItens': value.itemList,
};
I am new to flutter and I am learning APIs. My API model has a list named result. Can you please tell me how can I display that list and all other variables inside it by using snapshot.data
I am trying to declare
snapshot.data!.result but it is not working. Please give me the solution to this problem
Model code is below
class LeaguesModel {
LeaguesModel({
required this.success,
required this.result,
});
int success;
List<Result> result;
factory LeaguesModel.fromJson(Map<String, dynamic> json) => LeaguesModel(
success: json["success"],
result: List<Result>.from(json["result"].map((x) => Result.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"success": success,
"result": List<dynamic>.from(result.map((x) => x.toJson())),
};
}
class Result {
Result({
required this.leagueKey,
required this.leagueName,
required this.countryKey,
required this.countryName,
required this.leagueLogo,
required this.countryLogo,
});
String leagueKey;
String leagueName;
String countryKey;
String countryName;
String leagueLogo;
String countryLogo;
factory Result.fromJson(Map<String, dynamic> json) => Result(
leagueKey: json["league_key"],
leagueName: json["league_name"],
countryKey: json["country_key"],
countryName: json["country_name"],
leagueLogo: json["league_logo"],
countryLogo: json["country_logo"],
);
Map<String, dynamic> toJson() => {
"league_key": leagueKey,
"league_name": leagueName,
"country_key": countryKey,
"country_name": countryName,
"league_logo": leagueLogo,
"country_logo": countryLogo,
};
static List<Result> jsontoApiModel(List<dynamic> emote) => emote.map<Result>((item) => Result.fromJson(item)).toList();
}
I have the following JSON that is getting returned from an API call:
{
"categories": {
"mortgage": "Mortgage",
"haircutsClothing": "Haircuts & Clothing",
"homeRepairMaintenance": "Home Repair & Maintenance"
},
"other": {...}
}
And then I have this class acting as a model for the JSON data:
class APIData {
final Map<String, dynamic> parsedJson;
APIData({required this.parsedJson});
factory APIData.fromJson(Map<String, dynamic> parsedJson) {
List<Category> categories = parsedJson['categories']
.map((i) => Category.fromJson(i))
.toList();
return APIData(parsedJson: parsedJson);
}
}
class Category {
final String key;
final String category;
Category({required this.key, required this.category});
factory Category.fromJson(Map<String, dynamic> parsedJson) {
return Category(key: parsedJson['key'], category: parsedJson['value']);
}
}
When I run that, I get this error:
_TypeError (type '(dynamic) => Category' is not a subtype of type '(String, dynamic) => MapEntry<dynamic, dynamic>' of 'transform')
What am I doing wrong that is causing this error?
method .map on Map object has to return Map object too.
try this
final categoriesMap = parsedJson['categories'] as Map;
final List<Category> categories =
categoriesMap.entries
.map((e) => Category(key: e.key, category: e.value))
.toList();
entries from a Map returns an Iterable of Map Entry. then you can iterate through it and use key and value properties.
I am new to working with dart/flutter!
Tell me pls how to correctly implement an abstract class in which a factory method is needed
I have a large number of models with the same methods (factory Model.fromJsom, listFromJson)! I want to make an interface for such models, but I don’t understand how to make a factory method and a static in abstract class
Examples
class Post extends Equatable {
Post({
required this.id,
required this.title,
});
final int id;
final String title;
#override
List<Object> get props => [
id,
title,
];
factory Post.fromJson(dynamic json) {
return Post(
id: json['id'] as int,
title: json['name'] as String,
);
}
Map<String, dynamic> toJson() {
return {
'id': id,
'title': title,
};
}
static List<Post> listFromJson(List<dynamic> json) {
return json.map((value) => Post.fromJson(value)).toList();
}
#override
String toString() {
return '''Post { id: $id, title: $title }''';
}
}
I find it's always a headache to work with JSON array directly. The solution I find is to wrap the List inside another class, in this case ListPost as follows:
class Post {
final int id;
final String title;
Post({required this.id, required this.title});
factory Post.fromJson(Map<String, dynamic> json) => Post(
id: json['id'] as int,
title: json['title'] as String,
);
Map<String, dynamic> toJson() => <String, dynamic>{
'id': id,
'title': title,
};
}
class ListPost {
final List<Post> list;
ListPost({required this.list});
factory ListPost.fromJson(Map<String, dynamic> json) => ListPost(
list: (json['list'] as List<dynamic>)
.map((e) => Post.fromJson(e as Map<String, dynamic>))
.toList(),
);
Map<String, dynamic> toJson() => <String, dynamic>{
'list': list,
};
}
And the example JSON is like this:
{
"list": [
{"id": 1, "title": "TITLE_1"},
{"id": 2, "title": "TITLE_2"}
]
}
I hope this is workable for you.
You can simply use this website it will convert your json to a dart file and you can easily call the methods .fromJson and .toJson to convert from json to entity and vice versa quicktype website
JSON source
{
"greeting": "Welcome to quicktype!",
"instructions": [
"Type or paste JSON here",
"Or choose a sample above",
"quicktype will generate code in your",
"chosen language to parse the sample data"
]
}
Dart file
import 'dart:convert';
Welcome welcomeFromJson(String str) => Welcome.fromJson(json.decode(str));
String welcomeToJson(Welcome data) => json.encode(data.toJson());
class Welcome {
Welcome({
this.greeting,
this.instructions,
});
String greeting;
List<String> instructions;
factory Welcome.fromJson(Map<String, dynamic> json) => Welcome(
greeting: json["greeting"] == null ? null : json["greeting"],
instructions: json["instructions"] == null ? null : List<String>.from(json["instructions"].map((x) => x)),
);
Map<String, dynamic> toJson() => {
"greeting": greeting == null ? null : greeting,
"instructions": instructions == null ? null : List<dynamic>.from(instructions.map((x) => x)),
};
}