From json method in subclasses - json

I have a base class like:
class TransportationVehicle {
String name;
TransportationVehicle(this.name);
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['name'] = name;
return data;
}
}
And multiple sub-classes like:
class Bike extends TransportationVehicle {
int pedals;
Bike(String name, this.pedals) : super(name);
#override
Map<String, dynamic> toJson() {
final data = super.toJson();
data['pedals'] = pedals;
return data;
}
}
With that, I can transform a list of different types into a json string. But how would that work with fromJson functionality?

You can use the same idea from the toJson() method by using the base class.
import 'dart:convert';
class TransportationVehicle {
final String? name;
TransportationVehicle({
this.name,
});
factory TransportationVehicle.fromRawJson(String str) =>
TransportationVehicle.fromJson(json.decode(str));
String toRawJson() => json.encode(toJson());
factory TransportationVehicle.fromJson(dynamic json) => TransportationVehicle(
name: json['name'] == null ? null : json['name'] as String,
);
Map<String, dynamic> toJson() => {
'name': name == null ? null : name,
};
}
class Bike extends TransportationVehicle {
final int? pedals;
Bike({
String? name,
this.pedals,
}) : super(name: name);
factory Bike.fromRawJson(String str) => Bike.fromJson(json.decode(str));
String toRawJson() => json.encode(toJson());
factory Bike.fromJson(dynamic json) {
TransportationVehicle vehicle = TransportationVehicle.fromJson(json);
return Bike(
name: vehicle.name == null ? null : vehicle.name,
pedals: json['pedals'] == null ? null : json['pedals'] as int,
);
}
Map<String, dynamic> toJson() {
final data = super.toJson();
data['pedals'] = pedals == null ? null : pedals;
return data;
}
}

Related

Dart/Flutter : convert BigInt to json

I have an object with a bigint property i want to encode to json string:
class Token {
Token(
{
this.name,
this.supply,
});
String? name;
BigInt? supply;
factory Token.fromJson(Map<String, dynamic> json) {
return Token(
name: json['name'],
supply: json['supply'] == null ? null : BigInt.parse(json['supply']),
);
}
Map<String, dynamic> toJson() => <String, dynamic>{
'name': name,
'supply': supply == null ? null : supply!.toString(),
};
}
I create a method to encode json to string...
String tokenToJson(Token data) => jsonEncode(data.toJson())
... but the format is not correct because i need a bigint in the format json and not a string:
the result i want:
{"name":"Token","supply":100000000000000,}
the result i obtain:
{"name":"Token","supply":"100000000000000",}
jsonEncode doesn't manage bigint type and i found on internet only solutions with a conversion of the bigint to a string type.
NB: Same issue with jsonDecode
Thx
use this simple method instead of BigInt use just "num"
import 'dart:convert';
void main() {
String data = '''{"name":"Token","supply":100000000000000}''';
print("supply: ${Token.fromJson(jsonDecode(data)).supply}");
}
class Token {
Token({
required this.name,
required this.supply,
});
late final String name;
late final num supply;
Token.fromJson(Map<String, dynamic> json){
name = json['name'];
supply = json['supply'];
}
Map<String, dynamic> toJson() {
final _data = <String, dynamic>{};
_data['name'] = name;
_data['supply'] = supply;
return _data;
}
}
Please check the following answer, instead of calling toString method on supply just call toInt method which will prevents the quotations and you will get the formatted json as expected
import 'dart:convert';
class Token {
Token(
{
this.name,
this.supply,
});
String? name;
BigInt? supply;
factory Token.fromJson(Map<String, dynamic> json) {
return Token(
name: json['name'],
supply: json['supply'] == null ? null :BigInt.from(json['supply']) ,
);
}
Map<String, dynamic> toJson() => <String, dynamic>{
'name': name,
'supply': supply == null ? null : supply!.toInt(),
};
String tokenToJson(Token data) => json.encode(data.toJson());
}
void main() {
Token token = Token(name: "token_one",supply : BigInt.parse("10000061234567"));
print(token.tokenToJson(token));
}
Output
{"name":"token_one","supply":10000061234567}
You don't need to parse, you can use from for convert int to BigInt
import 'dart:convert';
void main() {
String data = '''{"name":"Token","supply":100000000000000}''';
print(Token.fromJson(jsonDecode(data)).toJson());
}
class Token {
String? name;
double? supply;
Token({this.name, this.supply});
Token.fromJson(Map<String, dynamic> json) {
name = json['name'];
supply = json['supply'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['name'] = name;
data['supply'] = supply;
return data;
}
}

Flutter Firestore fromJson Return Null?

I've been trying this but it keeps returning null where am I doing wrong?
class UserData {
final String? name;
UserData(
{this.name});
Map<String, dynamic> toJson() {
return {
'name': name,
};
}
UserData.fromJson(Map<String, dynamic> doc)
: this(name: doc['name']! as String);
factory UserData.fromDocument(DocumentSnapshot doc) {
return UserData.fromJson(doc.data() as Map<String, dynamic>);
}
}
and im trying like that
factory UserData.fromDocument(DocumentSnapshot doc) {
Map<String, dynamic> data = doc.data() as Map<String, dynamic>;
print(data['name']); // data is retuning correct
UserData user = UserData.fromJson(doc.data() as Map<String, dynamic>);
print(user.name); // data is returning null
return UserData.fromJson(doc.data() as Map<String, dynamic>);
}
Change this:
UserData.fromJson(Map<String, dynamic> doc)
: this(name: doc['name']! as String);
to, because this() would return a completely new class instance:
UserData.fromJson(Map<String, dynamic> doc)
: name = doc['name']! as String;

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

How can i deserialize my json in Flutter/dart

I'm quite new to flutter and right now i'm stucked in desterilize the json string into my class.
Appreciate your help on this.
This is my json
[
{
"itemno": "4800888136473",
"itemname": "AXE DEO AFRICA 150ML",
},
{
"itemno": "4800888141125",
"itemname": "AXE DEO BODYSPRAY DARK TMPTTN 150ML",
}
]
And my JSON Class
class ListItemList{
ListItemList({
this.itemno,
this.itemname,
});
String itemno;
String itemname;
factory ListItemList.fromJson(Map<String, dynamic> json) =>
ListItemList(
itemno: json["itemno"],
itemname: json["itemname"],
);
}
How i call
List<ListItemList> result =
ListItemList.fromJson(jsonDecode(response.body));
Check this link "https://app.quicktype.io/"
And paste your json code left side and add class model name.
for eg.
import 'dart:convert';
List<User> userFromJson(String str) => List<User>.from(json.decode(str).map((x) => User.fromJson(x)));
String userToJson(List<User> data) => json.encode(List<dynamic>.from(data.map((x) => x.toJson())));
class User {
User({
this.itemno,
this.itemname,
});
String itemno;
String itemname;
factory User.fromJson(Map<String, dynamic> json) => User(
itemno: json["itemno"] == null ? null : json["itemno"],
itemname: json["itemname"] == null ? null : json["itemname"],
);
Map<String, dynamic> toJson() => {
"itemno": itemno == null ? null : itemno,
"itemname": itemname == null ? null : itemname,
};
}
//Add below code in service
static Future<List<User>> getUsers() async {
List<User> users = usersFromJson(response.body));
return users;
}
// call service in specific page
List _users;
#override
void initState() {
super.initState();
ApiService.getUsers().then((value) {
setState(() {
_users = value;
});
})
}
Use map to iterate over the JSON which is a list.
final List<ListItemList> result = (jsonDecode(response.body) as List)
.map((e) => ListItemList.fromJson(e))
.toList();
Go to this URL and paste your JSON. It will convert it to both fromJson (json to dart object conversion) and toJson (dart object to json conversion) function.
Here is as example of fromJson and toJosn according to the Json you provided
class List {
List<Items> items;
List({this.items});
List.fromJson(Map<String, dynamic> json) {
if (json['items'] != null) {
items = new List<Items>();
json['items'].forEach((v) {
items.add(new Items.fromJson(v));
});
}
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
if (this.items != null) {
data['items'] = this.items.map((v) => v.toJson()).toList();
}
return data;
}
}
class Items {
String itemno;
String itemname;
Items({this.itemno, this.itemname});
Items.fromJson(Map<String, dynamic> json) {
itemno = json['itemno'];
itemname = json['itemname'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['itemno'] = this.itemno;
data['itemname'] = this.itemname;
return data;
}
}
As i mentioned it is a list. Deal with list like;
List<ListItemList> result;
var a = jsonDecode(response.body);
// I can not compile this part you can check syntax
a.forEach((element)
at= ListItemList.fromJson(element);
result.add(at);
);

Flutter error: the argument type 'dynamic' can't be assigned to the parameter type 'Iterable<dynamic>'

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