I have a class "SnapShot" with some member variables like a DateTime and a double. I have written the fromJson / toJson like this:
class SnapShot {
SnapShot (this.date, this.value);
final DateTime date;
final double value;
SnapShot.fromJson(Map<String, dynamic> json)
: date = DateTime.parse(json['date']),
value = json['value']();
Map<String, dynamic> toJson() =>
{
'date': date.toString(),
'value': value
};
}
I need to (de)serialize a list of these objects (List) to/from json file.
What is the correct way to do this?
This should do the trick:
import 'dart:convert';
class SnapShot {
SnapShot(this.date, this.value);
final DateTime date;
final double value;
SnapShot.fromJson(Map<String, dynamic> json)
: date = DateTime.parse(json['date']),
value = json['value'];
Map<String, dynamic> toJson() => {'date': date.toString(), 'value': value};
#override
String toString() => 'date: $date, value: $value';
}
void main() {
final list = [SnapShot(DateTime.now(), 0.4), SnapShot(DateTime.now(), 1.5)];
final asJson = json.encode(list);
final decodedJson = json.decode(asJson) as List;
final snapShots = decodedJson.map((map) => SnapShot.fromJson(map)).toList();
print(snapShots);
}
Related
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;
}
}
I am new to Dart and trying to deserialize some json, but I can't quite figure out the trick.
I am able to cast the Map in main as shown, but the commented code does not work and I can't figure out why. I feel like there must be an easier way to do this (outside of using a package for code generation), but I'm not sure what that is.
import 'dart:convert';
import 'dart:io';
class Book {
final String title;
final String path;
Book(this.title, this.path);
Book.fromJson(Map<String, dynamic> content)
: title = content['title'],
path = content['path'];
Map<String, dynamic> toJson() =>
{
'title': title,
'path': path,
};
String toString() {
return '{ title: $title, path: $path }';
}
}
class Books {
final Map<String, Book> bookList;
Books(this.bookList);
// Books.fromJson(Map<String, dynamic> content)
// : bookList = Map<String, Book>.from(jsonDecode(jsonDecode(content)['books']).map((k,v) => MapEntry(k as String, Book.fromJson(v))));
Map<String, dynamic> toJson() =>
{
'books': jsonEncode(bookList),
};
String toString() {
return bookList.toString();
}
}
void main() {
Map<String, Book> bookList = {
"foo": Book("Foo", "/foo"),
"bar": Book("Bar", "/bar"),
};
Books books = Books(bookList);
print(books);
String content = jsonEncode(books);
print(content);
// print(Books.fromJson(jsonDecode(content)));
Map<String, Book> m = Map<String, Book>.from(jsonDecode(jsonDecode(content)['books']).map((k,v) => MapEntry(k as String, Book.fromJson(v))));
print(m);
}
Oops, I needed to remove an invocation of jsonDecode from Books.fromJson...
Books.fromJson(Map<String, dynamic> content)
: bookList = Map<String, Book>.from(jsonDecode((content)['books']).map((k,v) => MapEntry(k as String, Book.fromJson(v))));
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)';
}
Trying to convert my json to objects in Dart/Flutter using the json_serializable. I cannot seem to find a way to access a nested ID (data is coming from MongoDB thus the $ in the json).
Here is the json:
{
"_id": {
"$oid": "5c00b227" <-- this is what I am trying to access
},
"base": 1,
"tax": 1,
"minimum": 5,
"type": "blah"
}
Result:
class Thing {
final int id;
final String base;
final String tax;
final String type;
final int minimum;
}
It is not possible with json_serializable package itself. You have to create separate objects for getting this nested data.
Look the discussion here
https://github.com/google/json_serializable.dart/issues/490
But, there is possible way to get nested fields with added converter (solution was found here https://github.com/google/json_serializable.dart/blob/master/example/lib/nested_values_example.dart)
import 'package:json_annotation/json_annotation.dart';
part 'nested_values_example.g.dart';
/// An example work-around for
/// https://github.com/google/json_serializable.dart/issues/490
#JsonSerializable()
class NestedValueExample {
NestedValueExample(this.nestedValues);
factory NestedValueExample.fromJson(Map<String, dynamic> json) =>
_$NestedValueExampleFromJson(json);
#_NestedListConverter()
#JsonKey(name: 'root_items')
final List<String> nestedValues;
Map<String, dynamic> toJson() => _$NestedValueExampleToJson(this);
}
class _NestedListConverter
extends JsonConverter<List<String>, Map<String, dynamic>> {
const _NestedListConverter();
#override
List<String> fromJson(Map<String, dynamic> json) => [
for (var e in json['items'] as List)
(e as Map<String, dynamic>)['name'] as String
];
#override
Map<String, dynamic> toJson(List<String> object) => {
'items': [
for (var item in object) {'name': item}
]
};
}
try this,
class Thing {
int id;
String base;
String tax;
String type;
int minimum;
Thing({
this.id,
this.base,
this.tax,
this.type,
this.minimum,
});
factory Thing.fromJson(Map<String, dynamic> json) {
return Thing(
id: json['_id']["oid"],
base: json['base'].toString(),
tax: json['tax'].toString(),
type: json['type'].toString(),
minimum: json['minimum'],
);
}
}
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;
}
}