How to parse json array into list in dart? - json

As for the script below, I have two different json for single record and multiple record as a list. I can parse the single data using the Person class. For the json with a list, I'm using ther PersonList class but I'm getting an error because the json key result is not needed anymore. Is there a way to parse the list without changing the Person class? Or should I not use the PersonList class and just create a List<Person>?
I saw this example but its only working if the json is a whole list like this
var jsonResponse = convert.jsonDecode(rawJsonMulti) as List;
return jsonResponse.map((p) => Person.fromJson(p).toList();
Can you show me how to use the above script using my json. Thanks.
import 'dart:convert';
void main() {
String rawJsonMulti = '{"result": [{"name":"Mary","age":30},{"name":"John","age":25}]}';
String rawJsonSingle = '{"result": {"name":"Mary","age":30}}';
// Working for non list json
// final result = json.decode(rawJsonSingle);
// var obj = Person.fromJson(result);
// print(obj.name);
final result = json.decode(rawJsonMulti);
var obj = PersonList.fromJson(result);
print(obj.listOfPerson[0].name);
}
class PersonList {
final List<Person> listOfPerson;
PersonList({this.listOfPerson});
factory PersonList.fromJson(Map<String, dynamic> json) {
var personFromJson = json['result'] as List;
List<Person> lst =
personFromJson.map((i) => Person.fromJson(i)).toList();
return PersonList(listOfPerson: lst);
}
}
class Person {
String name;
int age;
//will only work on result is not a list
Person({this.name, this.age});
factory Person.fromJson(Map<String, dynamic> json) {
return Person(name: json['result']['name'],
age: json['result']['age']);
}
// This will work on json with list but not in single
// factory Person.fromJson(Map<String, dynamic> json) {
// return Person(name: json['name'],
// age: json['age']);
// }
}

If you convert the dynamic to a List<dynamic> you can map each element in the jsonDecoded list.
Example:
import 'dart:convert';
final decodedJson = jsonDecode(rawJsonMulti) as List<dynamic>;
final personList = decodedJson
.map((e) => Person.fromJson(
e as Map<String, dynamic>))
.toList();
return PersonList(listOfPerson: personList);
```

Try take a look at this solution where I have fixed your code:
import 'dart:convert';
void main() {
const rawJsonMulti =
'{"result": [{"name":"Mary","age":30},{"name":"John","age":25}]}';
const rawJsonSingle = '{"result": {"name":"Mary","age":30}}';
final resultMulti = json.decode(rawJsonMulti) as Map<String, dynamic>;
final personListMulti = PersonList.fromJson(resultMulti);
print(personListMulti.listOfPerson[0]); // Mary (age: 30)
print(personListMulti.listOfPerson[1]); // John (age: 25)
final resultSingle = json.decode(rawJsonSingle) as Map<String, dynamic>;
final personListSingle = PersonList.fromJson(resultMulti);
print(personListSingle.listOfPerson[0]); // Mary (age: 30)
}
class PersonList {
final List<Person> listOfPerson;
PersonList({this.listOfPerson});
factory PersonList.fromJson(Map<String, dynamic> json) {
if (json['result'] is List) {
final personsFromJson = json['result'] as List;
return PersonList(listOfPerson: [
...personsFromJson
.cast<Map<String, Object>>()
.map((i) => Person.fromJson(i))
]);
} else {
final personFromJson = json['result'] as Map<String, Object>;
return PersonList(listOfPerson: [Person.fromJson(personFromJson)]);
}
}
}
class Person {
String name;
int age;
Person({this.name, this.age});
factory Person.fromJson(Map<String, dynamic> json) {
return Person(name: json['name'] as String, age: json['age'] as int);
}
#override
String toString() => '$name (age: $age)';
}

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

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

json encode (List of object) - String to decode (List of object)

My list is too long. So, I encode and save it to the database. I want to decode it. How do I do it?
encode way,
String shoppingCartToJson(List<ShoppingCartModel> data) => jsonEncode(data.map((i) => i.toMap()).toList()).toString();
How to decode?
I tried, but return type is String not List of object
List<ShoppingCartModel> shoppingFromJson(String str) => jsonDecode(str);
In your ShoppingCartModel class you should have functions to encode and decode, to the type and from dynamic respectively.
So your ShoppingCartModel class should look like (assuming the parameters inside the class):
class ShoppingCartModel {
String itemId;
String itemName;
double quantity;
ShoppingCartModel.fromJson(Map<String, dynamic> json) {
if (json == null) return;
itemId = json['item_id'];
itemName = json['item_name'];
quantity = json['quantity'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['item_id'] = this.itemId;
data['item_name'] = this.itemName;
data['quantity'] = this.quantity;
return data;
}
}
And then you can encode and decode using:
Encode:
json.encode(data);
Decode:
List<dynamic> decodedData = json.decode(strData);
List<ShoppingCartModel> dataDecodedList = List<ShoppingCartModel>.from(
dataDecoded.map((x) => ShoppingCartModel.fromJson(x)),
);

Parse JSON to convert into Model class

I'm not able to convert server response to model class. The following is my code.
void main() {
//JSON to parse
var strJson = """{
\"person\": [
{\"name\": \"Mahendra\", \"age\": 28},
{\"name\": \"Test\", \"age\": 25}
]
}""";
var data = json.decode(strJson);
print("json: $data");
var result = PersonResponse<Person>.fromJSON(data);
print("result: ${result.persons}");
}
Model Class
class Person {
String name;
int age;
Person.fromJSON(Map json) {
this.name = json["name"];
this.age = json["age"];
}
}
class PersonResponse<T> {
List<T> persons;
PersonResponse.fromJSON(Map json) {
this.persons = json["person"];
}
}
When I run this code I'm not able to convert server response to model class. Getting following error...
Unhandled Exception: type List<dynamic> is not a subtype of type List<Person>
Whats wrong with my code. Any suggestions?
try
// To parse this JSON data, do
//
// final person = personFromJson(jsonString);
import 'dart:convert';
Person personFromJson(String str) => Person.fromJson(json.decode(str));
String personToJson(Person data) => json.encode(data.toJson());
class Person {
List<PersonElement> person;
Person({
this.person,
});
factory Person.fromJson(Map<String, dynamic> json) => Person(
person: List<PersonElement>.from(json["person"].map((x) => PersonElement.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"person": List<dynamic>.from(person.map((x) => x.toJson())),
};
}
class PersonElement {
String name;
int age;
PersonElement({
this.name,
this.age,
});
factory PersonElement.fromJson(Map<String, dynamic> json) => PersonElement(
name: json["name"],
age: json["age"],
);
Map<String, dynamic> toJson() => {
"name": name,
"age": age,
};
}
I found 3 options:
You can either abandon usage of generics and replace List<T> persons; with List<dynamic> persons;. Your code will actually work with only this change.
You can abandon usage of generics and replace List<T> persons; with List<Person> and map it in fromJson.
class PersonResponse {
List<Person> persons;
PersonResponse.fromJSON(Map json) {
List<dynamic> list = json["person"];
persons = list.map((element) => Person.fromJSON(element)).toList();
}
}
Keep generics but restrict in to something serializable, to something like this:
class PersonResponse<T extends JsonSerializable> {
List<T> persons;
PersonResponse.fromJSON(Map json) {
List<dynamic> list = json["person"];
persons = list.map((element) => T.fromJSON(element)).toList();
}
}
Don't convert JSON into dart object manually. Because some time JSON response are very complex So it may happen you can write incorrect data type. So always use Online JSON to Dart Convertor. It is free to use. It will reduce the chance of error.

how to convert json string to json object in dart flutter?

I have string like this,
{id:1, name: lorem ipsum, address: dolor set amet}
And I need to convert that string to json, how I can do it in dart flutter? thank you so much for your help.
You have to use json.decode. It takes in a json object and let you handle the nested key value pairs. I'll write you an example
import 'dart:convert';
// actual data sent is {success: true, data:{token:'token'}}
final response = await client.post(url, body: reqBody);
// Notice how you have to call body from the response if you are using http to retrieve json
final body = json.decode(response.body);
// This is how you get success value out of the actual json
if (body['success']) {
//Token is nested inside data field so it goes one deeper.
final String token = body['data']['token'];
return {"success": true, "token": token};
}
Create a model class
class User {
int? id;
String? name;
String? address;
User({this.id, this.name, this.address});
User.fromJson(Map<String, dynamic> json) {
id = json['id'];
name = json['name'];
address = json['address'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = this.id;
data['name'] = this.name;
data['address'] = this.address;
return data;
}
}
In the logic section
String data ='{id:1, name: lorem ipsum, address: dolor set amet}';
var encodedString = jsonEncode(data);
Map<String, dynamic> valueMap = json.decode(encodedString);
User user = User.fromJson(valueMap);
Also need to import
import 'dart:convert';
You can also convert JSON array to list of Objects as following:
String jsonStr = yourMethodThatReturnsJsonText();
Map<String,dynamic> d = json.decode(jsonStr.trim());
List<MyModel> list = List<MyModel>.from(d['jsonArrayName'].map((x) => MyModel.fromJson(x)));
And MyModel is something like this:
class MyModel{
String name;
int age;
MyModel({this.name,this.age});
MyModel.fromJson(Map<String, dynamic> json) {
name= json['name'];
age= json['age'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['name'] = this.name;
data['age'] = this.age;
return data;
}
}
String name = "{click_action: FLUTTER_NOTIFICATION_CLICK, sendByImage: https://ujjwalchef.staging-server.in/uploads/users/1636620532.png, status: done, sendByName: mohittttt, id: HM11}";
List<String> str = name.replaceAll("{","").replaceAll("}","").split(",");
Map<String,dynamic> result = {};
for(int i=0;i<str.length;i++){
List<String> s = str[i].split(":");
result.putIfAbsent(s[0].trim(), () => s[1].trim());
}
print(result);
}
You must need to use this sometimes
Map<String, dynamic> toJson() {
return {
jsonEncode("phone"): jsonEncode(numberPhone),
jsonEncode("country"): jsonEncode(country),
};
}
This code give you a like string {"numberPhone":"+225657869", "country":"CI"}. So it's easy to decode it's after like that
json.decode({"numberPhone":"+22565786589", "country":"CI"})
You must import dart:encode libary. Then use the jsonDecode function, that will produce a dynamic similar to a Map
https://api.dartlang.org/stable/2.2.0/dart-convert/dart-convert-library.html
For converting string to JSON we have to modify it with custom logic, in here first we remove all symbols of array and object and then we split text with special characters and append with key and value(for map).
Please try this code snippet in dartpad.dev
import 'dart:developer';
void main() {
String stringJson = '[{product_id: 1, quantity: 1, price: 16.5}]';
stringJson = removeJsonAndArray(stringJson);
var dataSp = stringJson.split(',');
Map<String, String> mapData = {};
for (var element in dataSp) {
mapData[element.split(':')[0].trim()] = element.split(':')[1].trim();
}
print("jsonInModel: ${DemoModel.fromJson(mapData).toJson()}");
}
String removeJsonAndArray(String text) {
if (text.startsWith('[') || text.startsWith('{')) {
text = text.substring(1, text.length - 1);
if (text.startsWith('[') || text.startsWith('{')) {
text = removeJsonAndArray(text);
}
}
return text;
}
class DemoModel {
String? productId;
String? quantity;
String? price;
DemoModel({this.productId, this.quantity, this.price});
DemoModel.fromJson(Map<String, dynamic> json) {
log('json: ${json['product_id']}');
productId = json['product_id'];
quantity = json['quantity'];
price = json['price'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['product_id'] = productId;
data['quantity'] = quantity;
data['price'] = price;
return data;
}
}