Flutter class in class to json decode - json

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>);
}
}

Related

How do I get the value from nested locally stored json-file in Flutter?

I'm trying to get the nested values from my locally stored json file with Flutter.
I can get the "outer" values, but I haven't been able to get the "inner" ones. I have googled and searched here, but I still can't make it work, so any help is much appreciated.
I put the code in a sandbox to make it easier to see.
https://codesandbox.io/s/loving-thunder-meklbc?file=/lib/main.dart
If you rather look here this is what some files look like:
json:
[{
"id":184423,
"created":"2022-11-18T09:32:56.000Z",
"raw_data":[
{"measurement_id":18,"index":0,"substance":655,"pressure":20,"temperature":30.03},
{"measurement_id":18,"index":1,"substance":648,"pressure":38,"temperature":30.03},
{"measurement_id":18,"index":2,"substance":636,"pressure":90,"temperature":30.02},
{"measurement_id":18,"index":3,"substance":623,"pressure":130,"temperature":30.05},
{"measurement_id":18,"index":4,"substance":598,"pressure":147,"temperature":29.99}
]
},
{
"id":184423,
"created":"2022-11-19T09:32:56.000Z",
"raw_data":[
{"measurement_id":19,"index":0,"substance":586,"pressure":160,"temperature":30.05},
{"measurement_id":19,"index":1,"substance":564,"pressure":170,"temperature":29.99},
{"measurement_id":19,"index":2,"substance":553,"pressure":173,"temperature":30},
{"measurement_id":19,"index":3,"substance":544,"pressure":162,"temperature":30.02},
{"measurement_id":19,"index":4,"substance":538,"pressure":164,"temperature":30.01}
]
}
]
handler:
import 'dart:convert';
import 'package:flutter/services.dart' as rootbundle;
import '../model/usermodel.dart';
Future<List<UserModel>> readJsonData() async {
final jsondata = await rootbundle.rootBundle.loadString('/userdata.json');
final list = json.decode(jsondata) as List<dynamic>;
//print(list);
return list.map((e) => UserModel.fromJson(e)).toList();
}
model:
// ignore_for_file: non_constant_identifier_names
class UserModel {
late int? id, measurementId, index, substance, pressure;
late double? temperature;
UserModel(
this.id,
this.measurementId,
this.index,
this.substance,
this.pressure,
this.temperature,
);
UserModel.fromJson(Map<String, dynamic> json) {
id = json["id"];
measurementId = json['measurement_id'];
index = json['index'];
substance = json['substance'];
pressure = json['pressure'];
temperature = json['temperature'];
}
}
class UserModel {
UserModel(this.id, this.raw_data);
/// Creates a UserModel from Json map
factory UserModel.fromJson(Map<String, dynamic> json) => UserModel(
json['id'] as int?,
(json['raw_data'] as List<dynamic>?)
?.map((e) => Data.fromJson(e as Map<String, dynamic>))
.toList(),
);
final int? id;
final List<Data>? raw_data;
}
//Data
class Data {
Data(
this.measurement_id,
this.index,
this.substance,
this.pressure,
this.temperature,
);
final int? measurement_id;
final int? index;
final int? substance;
final int? pressure;
final double? temperature;
/// Creates a Data from Json map
factory Data.fromJson(Map<String, dynamic> json) => Data(
json['measurement_id'] as int?,
json['index'] as int?,
json['substance'] as int?,
json['pressure'] as int?,
(json['temperature'] as num?)?.toDouble(),
);
}
List<UserModel> models = [];
for (var item in list) {
models.addAll(item.map((e) => UserModel.fromJson(e['id'], e['raw_data'])));
}
return models;
UserModel.fromJson(int id, Map<String, dynamic> json) {
this.id = id; // parse json (raw_data)
}

_TypeError (type 'Null' is not a subtype of type 'String') Flutter-jsonserialisable

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 Serialize GeoPoint flutter?

flutter pub run build_runner build gives an error on geoPoint. Error says: To support the type GeoPoint you can: Use JsonConverter.
How can I implement it?
class
...
#JsonSerializable()
class Person{
late final String name;
final List<Location> location;
Person(
{required this.uid,
required this.name,
required this.location});
factory Person.fromJson(Map<String, dynamic> json) => _$PersonFromJson(json);
Map<String, dynamic> toJson() => _$PersonToJson(this);
}
#JsonSerializable()
class Location {
String name;
GeoPoint geoPoint;
Location({required this.name, required this.geoPoint});
factory Location.fromJson(Map<String, dynamic> json) =>
_$LocationFromJson(json);
Map<String, dynamic> toJson() => _$LocationToJson(this);
}
Example for Colors :
#JsonSerializable()
class Line {
Line({required this.name, required this.color});
factory Line.fromJson(Map<String, dynamic> json) => _$LineFromJson(json);
String name;
#ColorSerializer()
Color color;
Map<String, dynamic> toJson() => _$LineToJson(this);
}
class ColorSerializer implements JsonConverter<Color, int> {
const ColorSerializer();
#override
Color fromJson(int json) => Color(json);
#override
int toJson(Color color) => color.value;
}
Your Code should be something like this:
#JsonSerializable()
class Line {
Line({required this.name, required this.color});
factory Line.fromJson(Map<String, dynamic> json) => _$LineFromJson(json);
String name;
#GeoPointSerializer()
GeoPoint geoPoint;
Map<String, dynamic> toJson() => _$LineToJson(this);
}
class GeoPointSerializer implements JsonConverter<GeoJson, List<int,int>> {
const GeoPointSerializer();
#override
GeoPoint fromJson(List<int,int> json) => GeoPoint(x:json[0],json[1]);
#override
List<int,int> toJson(GeoPoint geoPoint) => [geoPoint.x,geoPoint.y];
}

Parsing json array response / flutter

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

Exception: type 'String' is not a subtype of type 'Map<String, dynamic>

Exception: type 'String' is not a subtype of type 'Map<String, dynamic>'
{"collection":{"data":"{\"id\": 1, \"name\": \"Marko\", \"picture\":
\"https://lh3.googleusercontent.com/a-/AAuE7mC1vqaKk_Eylt-fcKgJxuN96yQ7dsd2dBdsdsViK959TKsHQ=s96-
c\"}","statusCode":202,"version":"1.0"}}
This is the above json and i want to put it at User pojo class only the [data].
But it threw the above exception type.
class UserCollection {
final User data;
final int statusCode;
final String version;
UserCollection({this.data, this.statusCode, this.version});
factory UserCollection.fromJson(Map<String, dynamic> json) {
return UserCollection(
statusCode: json['statusCode'] as int,
data: User.fromJson(json['data']) ,
version: json['version'] as String );
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['data'] = this.data;
data['statusCode'] = this.statusCode;
data['version'] = this.version;
return data;
}
}
User Pojo class
#JsonSerializable()
class User {
final int id;
final String sub;
final String home;
final String work;
final String name;
final String mobileNo;
final String email;
final String favMechId;
final String appVersionCode;
final String picture;
final String serverTime;
final String dateCreated;
final String dateModified;
final String fcmTokenId;
User(
{this.id,
this.sub,
this.home,
this.work,
this.name,
this.mobileNo,
this.email,
this.favMechId,
this.appVersionCode,
this.picture,
this.serverTime,
this.dateCreated,
this.dateModified,
this.fcmTokenId});
factory User.fromJson(Map<String, dynamic> json) => _$UserFromJson(json);
Map<String,dynamic> toJson() => _$UserToJson(this);
I have referring this medium site for clarity, medium flutter json
but in vein more than 4 hours i couldn't what was wrong.
If change the User.from() to String then it's okay. But i need to parse the [data] from json to User pojo class.
Try below,
factory UserCollection.fromJson(Map<String, dynamic> json) {
return UserCollection(
statusCode: json['statusCode'] as int,
data: User.fromJson(json.decode(json['data'])),
version: json['version'] as String );
}
Change in data: User.fromJson(json.decode(json['data'])),