I used the json_serializable package to convert data to JSON format as a Dart class and I get an error, here is the deserialized class code
import 'package:json_annotation/json_annotation.dart';
part 'country.g.dart';
#JsonSerializable()
class Country {
final String name;
final List<String> topLevelDomain;
final String alpha2Code;
final String alpha3Code;
final List<String> callingCodes;
final String capital;
final List<String> altSpellings;
final String region;
final String continent;
final int population;
final List<int> latlng;
final String demonym;
final int area;
final double gini;
final List<String> timezones;
final List<String> borders;
final String nativeName;
final String numericCode;
final List<Currencies> currencies;
final List<Languages> languages;
final Translations translations;
final List<String> flags;
final List<RegionalBlocs> regionalBlocs;
final String cioc;
final bool independent;
Country(
{required this.name,
required this.topLevelDomain,
required this.alpha2Code,
required this.alpha3Code,
required this.callingCodes,
required this.capital,
required this.altSpellings,
required this.region,
required this.continent,
required this.population,
required this.latlng,
required this.demonym,
required this.area,
required this.gini,
required this.timezones,
required this.borders,
required this.nativeName,
required this.numericCode,
required this.currencies,
required this.languages,
required this.translations,
required this.flags,
required this.regionalBlocs,
required this.cioc,
required this.independent});
factory Country.fromJson(Map<String, dynamic> json) =>
_$CountryFromJson(json);
Map<String, dynamic> toJson() => _$CountryToJson(this);
}
#JsonSerializable()
class Currencies {
final String code;
final String name;
final String symbol;
Currencies({
required this.code,
required this.name,
required this.symbol,
});
factory Currencies.fromJson(Map<String, dynamic> json) =>
_$CurrenciesFromJson(json);
Map<String, dynamic> toJson() => _$CurrenciesToJson(this);
}
#JsonSerializable()
class Languages {
final String iso6391;
final String iso6392;
final String name;
final String nativeName;
Languages({
required this.iso6391,
required this.iso6392,
required this.name,
required this.nativeName,
});
factory Languages.fromJson(Map<String, dynamic> json) =>
_$LanguagesFromJson(json);
Map<String, dynamic> toJson() => _$LanguagesToJson(this);
}
#JsonSerializable()
class Translations {
final String br;
final String pt;
final String nl;
final String hr;
final String fa;
final String de;
final String es;
final String fr;
final String ja;
final String it;
final String hu;
Translations(
{required this.br,
required this.pt,
required this.nl,
required this.hr,
required this.fa,
required this.de,
required this.es,
required this.fr,
required this.ja,
required this.it,
required this.hu});
factory Translations.fromJson(Map<String, dynamic> json) =>
_$TranslationsFromJson(json);
Map<String, dynamic> toJson() => _$TranslationsToJson(this);
}
#JsonSerializable()
class RegionalBlocs {
final String acronym;
final String name;
final List<String> otherNames;
final List<String> otherAcronyms;
RegionalBlocs({
required this.acronym,
required this.name,
required this.otherNames,
required this.otherAcronyms,
});
factory RegionalBlocs.fromJson(Map<String, dynamic> json) =>
_$RegionalBlocsFromJson(json);
Map<String, dynamic> toJson() => _$RegionalBlocsToJson(this);
}
and here is the file generated by the package.
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'country.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
Country _$CountryFromJson(Map<String, dynamic> json) => Country(
name: json['name'] as String,
topLevelDomain: (json['topLevelDomain'] as List<dynamic>)
.map((e) => e as String)
.toList(),
alpha2Code: json['alpha2Code'] as String,
alpha3Code: json['alpha3Code'] as String,
callingCodes: (json['callingCodes'] as List<dynamic>)
.map((e) => e as String)
.toList(),
capital: json['capital'] as String,
altSpellings: (json['altSpellings'] as List<dynamic>)
.map((e) => e as String)
.toList(),
region: json['region'] as String,
this is the line that throws an exception
continent: json['continent'] as String,
//...
population: json['population'] as int,
latlng: (json['latlng'] as List<dynamic>).map((e) => e as int).toList(),
demonym: json['demonym'] as String,
area: json['area'] as int,
gini: (json['gini'] as num).toDouble(),
timezones:
(json['timezones'] as List<dynamic>).map((e) => e as String).toList(),
borders:
(json['borders'] as List<dynamic>).map((e) => e as String).toList(),
nativeName: json['nativeName'] as String,
numericCode: json['numericCode'] as String,
currencies: (json['currencies'] as List<dynamic>)
.map((e) => Currencies.fromJson(e as Map<String, dynamic>))
.toList(),
languages: (json['languages'] as List<dynamic>)
.map((e) => Languages.fromJson(e as Map<String, dynamic>))
.toList(),
translations:
Translations.fromJson(json['translations'] as Map<String, dynamic>),
flags: (json['flags'] as List<dynamic>).map((e) => e as String).toList(),
regionalBlocs: (json['regionalBlocs'] as List<dynamic>)
.map((e) => RegionalBlocs.fromJson(e as Map<String, dynamic>))
.toList(),
cioc: json['cioc'] as String,
independent: json['independent'] as bool,
);
Map<String, dynamic> _$CountryToJson(Country instance) => <String, dynamic>{
'name': instance.name,
'topLevelDomain': instance.topLevelDomain,
'alpha2Code': instance.alpha2Code,
'alpha3Code': instance.alpha3Code,
'callingCodes': instance.callingCodes,
'capital': instance.capital,
'altSpellings': instance.altSpellings,
'region': instance.region,
'continent': instance.continent,
'population': instance.population,
'latlng': instance.latlng,
'demonym': instance.demonym,
'area': instance.area,
'gini': instance.gini,
'timezones': instance.timezones,
'borders': instance.borders,
'nativeName': instance.nativeName,
'numericCode': instance.numericCode,
'currencies': instance.currencies,
'languages': instance.languages,
'translations': instance.translations,
'flags': instance.flags,
'regionalBlocs': instance.regionalBlocs,
'cioc': instance.cioc,
'independent': instance.independent,
};
Currencies _$CurrenciesFromJson(Map<String, dynamic> json) => Currencies(
code: json['code'] as String,
name: json['name'] as String,
symbol: json['symbol'] as String,
);
Map<String, dynamic> _$CurrenciesToJson(Currencies instance) =>
<String, dynamic>{
'code': instance.code,
'name': instance.name,
'symbol': instance.symbol,
};
Languages _$LanguagesFromJson(Map<String, dynamic> json) => Languages(
iso6391: json['iso6391'] as String,
iso6392: json['iso6392'] as String,
name: json['name'] as String,
nativeName: json['nativeName'] as String,
);
Map<String, dynamic> _$LanguagesToJson(Languages instance) => <String, dynamic>{
'iso6391': instance.iso6391,
'iso6392': instance.iso6392,
'name': instance.name,
'nativeName': instance.nativeName,
};
Translations _$TranslationsFromJson(Map<String, dynamic> json) => Translations(
br: json['br'] as String,
pt: json['pt'] as String,
nl: json['nl'] as String,
hr: json['hr'] as String,
fa: json['fa'] as String,
de: json['de'] as String,
es: json['es'] as String,
fr: json['fr'] as String,
ja: json['ja'] as String,
it: json['it'] as String,
hu: json['hu'] as String,
);
Map<String, dynamic> _$TranslationsToJson(Translations instance) =>
<String, dynamic>{
'br': instance.br,
'pt': instance.pt,
'nl': instance.nl,
'hr': instance.hr,
'fa': instance.fa,
'de': instance.de,
'es': instance.es,
'fr': instance.fr,
'ja': instance.ja,
'it': instance.it,
'hu': instance.hu,
};
RegionalBlocs _$RegionalBlocsFromJson(Map<String, dynamic> json) =>
RegionalBlocs(
acronym: json['acronym'] as String,
name: json['name'] as String,
otherNames: (json['otherNames'] as List<dynamic>)
.map((e) => e as String)
.toList(),
otherAcronyms: (json['otherAcronyms'] as List<dynamic>)
.map((e) => e as String)
.toList(),
);
Map<String, dynamic> _$RegionalBlocsToJson(RegionalBlocs instance) =>
<String, dynamic>{
'acronym': instance.acronym,
'name': instance.name,
'otherNames': instance.otherNames,
'otherAcronyms': instance.otherAcronyms,
};
please help me, it's the end of two months that I started Flutter and Dart and this problem blocks me completely, thank you in advance.
Change continent: json['continent'] as String to
continent: json['continent']??""
If you wish to convert it from the generator change the value of continent to null and generate. Which should result in it's type being dynamic
How can I use class in class value?
For example I have a class like below.
import 'dart:convert';
class Product {
final String productId;
final String productName;
final String productImageUrl;
final String productCategory;
Product(
{required this.productId,
required this.productName,
required this.productImageUrl,
required this.productCategory});
factory Product.fromJson(Map<String, dynamic> json) {
return Product(
productId: json['productId'],
productName: json['productName'],
productImageUrl: json['productImageUrl'],
productCategory: json['productCategory'],
);
}
static Map<String, dynamic> toMap(Product product) => {
'productId': product.productId,
'productName': product.productName,
'productImageUrl': product.productImageUrl,
'productCategory': product.productCategory,
};
static String encode(List<Product> products) => json.encode(
products
.map<Map<String, dynamic>>((product) => Product.toMap(product))
.toList(),
);
static List<Product> decode(String products) =>
(json.decode(products) as List<dynamic>)
.map<Product>((item) => Product.fromJson(item))
.toList();
}
And I can use encode and decode like this.
Encode:
final String encodedData = Product.encode([
Product(
productId: "1",
productName: "Americano",
productImageUrl: "assets/americano.jpeg",
productCategory: "Warm"),
Product(
productId: "2",
productName: "Latte",
productImageUrl: "assets/americano.jpeg",
productCategory: "Cold"),
]);
Decode:
List<Product> products;
products = Product.decode(encodedData);
Now here is my question. If I want to use this product class like list in another class. How can I write encode, decode and fromJson methods? Can you help me? And please give me example usages.
import 'dart:convert';
import 'package:orderapp/models/product.dart';
class Bill {
final String billNo;
final String billNumber;
final String tableNo;
final String orderDateTime;
final String orderWaiter;
final List<Product> products;
Bill({
required this.billNo,
required this.billNumber,
required this.tableNo,
required this.orderDateTime,
required this.orderWaiter,
required this.products,
});
}
The data class with JSON decoder and encoder support.
import 'dart:convert';
class Product {
final String productId;
final String productName;
final String productImageUrl;
final String productCategory;
Product({
required this.productId,
required this.productName,
required this.productImageUrl,
required this.productCategory,
});
Map<String, dynamic> toMap() => {
'productId': productId,
'productName': productName,
'productImageUrl': productImageUrl,
'productCategory': productCategory,
};
factory Product.fromMap(Map<String, dynamic> map) => Product(
productId: map['productId'] as String,
productName: map['productName'] as String,
productImageUrl: map['productImageUrl'] as String,
productCategory: map['productCategory'] as String,
);
String toJson() => json.encode(toMap());
factory Product.fromJson(String source) {
return Product.fromMap(json.decode(source) as Map<String, dynamic>);
}
}
Did this according to this manual
https://www.bezkoder.com/dart-flutter-parse-json-string-array-to-object-list/
Dart/Flutter parse array of JSON objects into List
JSON that comes from the server
{"myChannels":[{"id":"2","name":"channel2test","imageUrl":"image1.png"},{"id":"2","name":"channel2test","imageUrl":"image2.png"}]}
Model Class
class ChannelModel {
String channelID;
String channelName;
String imageUrl;
ChannelModel(this.channelID, this.channelName, this.imageUrl);
factory ChannelModel.parsingChannels(dynamic json) {
return ChannelModel(json['channelID'] as String,
json['channelName'] as String, json['imageUrl'] as String);
}
#override
String toString() {
return '{ ${this.channelID}, ${this.channelName}, ${this.imageUrl} }';
}
}
Main block
try {
final response = await http.post(
url,
body: json.encode({
'action': 'getMyChannels',
'userID': userID,
'returnSecureToken': true,
}),
);
// print(jsonDecode(response.body));
var extractedData =
jsonDecode(response.body)['myChannels'] as List<dynamic>;
List<ChannelModel> channelObjects = extractedData
.map((cJson) => ChannelModel.parsingChannels(cJson))
.toList();
print(channelObjects);
channelObjects.forEach((Data) {
print('test');
});
the results is the following...
print(channelObjects) > outputs > []
print('test') > not working , channelObjects not looping
I would suggest serializing your response to dart classes. It would be much easier to access the data you want.
class ApiResponse {
ApiResponse({
required this.myChannels,
});
List<MyChannel> myChannels;
factory ApiResponse.fromJson(Map<String, dynamic> json) => ApiResponse(
myChannels: List<MyChannel>.from(
json["myChannels"].map((x) => MyChannel.fromJson(x)),
),
);
}
class MyChannel {
MyChannel({
required this.id,
required this.name,
required this.imageUrl,
});
String id;
String name;
String imageUrl;
factory MyChannel.fromJson(Map<String, dynamic> json) => MyChannel(
id: json["id"],
name: json["name"],
imageUrl: json["imageUrl"],
);
}
Then you can use it this way :
final extractedData = ApiResponse.fromJson(json.decode(response.body) as Map<String, dynamic>);
And access the data you want
extractedData.myChannels[0].id
extractedData.myChannels[0].name
extractedData.myChannels[0].imageUrl
for (var ch in extractedData.myChannels){
print(ch.id);
print(ch.name);
print(ch.imageUrl);
}
part 'example.g.dart';
#JsonSerializable()
class Channel{
final String id;
final String name;
final String? imageUrl;
Channel({required this.id, required this.name, this.imageUrl});
factory Channel.fromJson(Map<String, dynamic> json) => _$ChannelFromJson(json);
Map<String, dynamic> toJson() => _$ChannelToJson(this);
}
#JsonSerializable()
class ChannelList{
final List<Channel> myChannels;
ChannelList({required this.myChannels});
factory ChannelList.fromJson(Map<String, dynamic> json) => _$ChannelListFromJson(json);
Map<String, dynamic> toJson() => _$ChannelListToJson(this);
}
final extractedData = ChannelList.fromJson(json.decode(response.body));
https://pub.dev/packages/json_serializable
Using JsonSerializable more useful and understandable. You can read documentation of that package
Kindly assist.
I am attempting to create a model using the JSON to Dart tool https://app.quicktype.io/
The aim is to retrieve a list of all companies (with their properties) from a JSON API.
I am getting the below errors:
the argument type 'dynamic' can't be assigned to the parameter type Map<String, dynamic>
the argument type 'dynamic' can't be assigned to the parameter type Iterable
the argument type 'dynamic' can't be assigned to the parameter type Int
Please refer to the image below.
the argument type 'dynamic' can't be assigned to the parameter type...
Thank you.
I have tested this class and it works without errors
import 'dart:convert';
CompanyModel companyModelFromJson(String str) => CompanyModel.fromJson(json.decode(str));
String companyModelToJson(CompanyModel data) => json.encode(data.toJson());
class CompanyModel {
CompanyModel({
this.companies,
});
List<Company> companies;
factory CompanyModel.fromJson(Map<String, dynamic> json) => CompanyModel(
companies: List<Company>.from(json["companies"].map((x) => Company.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"companies": List<dynamic>.from(companies.map((x) => x.toJson())),
};
}
class Company {
Company({
this.id,
this.name,
});
int id;
String name;
factory Company.fromJson(Map<String, dynamic> json) => Company(
id: json["id"],
name: json["name"],
);
Map<String, dynamic> toJson() => {
"id": id,
"name": name,
};
}
As alternative you can use this code from JsonToDart
class CompanyModel {
List<Companies> companies;
CompanyModel({this.companies});
CompanyModel.fromJson(Map<String, dynamic> json) {
if (json['companies'] != null) {
companies = new List<Companies>();
json['companies'].forEach((v) {
companies.add(new Companies.fromJson(v));
});
}
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
if (this.companies != null) {
data['companies'] = this.companies.map((v) => v.toJson()).toList();
}
return data;
}
}
class Companies {
int id;
String name;
Companies({this.id, this.name});
Companies.fromJson(Map<String, dynamic> json) {
id = json['id'];
name = json['name'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = this.id;
data['name'] = this.name;
return data;
}
}
I'm using the packages: https://pub.dev/packages/json_annotation, https://pub.dev/packages/json_serializable
I want to encode/decode a list of objects in my flutter app. The class which is in the list is as follows:
#JsonSerializable()
class Trial {
final ProtocolType type;
List<List<double>> data;
#JsonKey()
final DateTime date;
Trial({this.type, this.data, this.date});
Map<String, dynamic> toMap() {
return {'type': this.type, 'data': this.data, 'date': this.date};
}
factory Trial.fromJson(Map<String, dynamic> json) => _$TrialFromJson(json);
Map<String, dynamic> toJson() => _$TrialToJson(this);
}
I want to decode/encode a list of these items, and I couldn't figure out how else to do it so I made a new class:
#JsonSerializable()
class TrialList {
final List<Trial> trials;
TrialList({this.trials});
factory TrialList.fromJson(List json) => _$TrialListFromJson(json);
List toJson() => _$TrialListToJson(this);
}
Notice the List toJson() in this new class. It seems Json_serializable only wants me to decode/encode maps, is there any way to support lists?
Solution:
#JsonSerializable()
class TrialList {
final List<Trial> trials;
TrialList({this.trials});
factory TrialList.fromJson(json) => _$TrialListFromJson({'trials': json});
List toJson() => _$TrialListToJson(this)['trials'];
}
credit to Null from the /r/FlutterDev discord