I try to sign up as a user to a back-end that takes some values as String and then a class that is called profile with some Strings within the Profile class. So in short the back-end wants some strings and a class.
Map data = {
'username': name,
'email': email,
'password1': password1,
'password2': password2,
'profile': Profile(countryIsoCode: country),
};
This is how I declare field for backend. And I want to declare countryIsoCode as: 'country_iso_code': country,'
But this is not possible within the Profile. And the backend don't get the value for countryIsoCode but when I did: 'country_iso_code': country,' outside the profile it worked but then the back-end does not get a 'profile' value.
In my class I have also this function, but I don't know is I need it.
Map toJson() => {
'countryIsoCode': countryIsoCode,
};
Then I send body to backend.
String body = jsonEncode(data);
I expect either to make the object to jsonObject or declare 'countryIsoCode': countryIsoCode within Profile.
You can use your the toJson() method on your profile object to convert it to a dictionary that in turn can be converted to a JSON string and sent to the backend.
It will look something like assuming that all the other variables like name, email etc. are strings.
var profile = Profile(countryIsoCode: country);
Map<string, dynamic> dataTransferObject = {
'username': name,
'email': email,
'password1': password1,
'password2': password2,
'profile': profile.toJson(), // Important to call toJson here
};
var json = jsonEncode(dataTransferObject); // jsonEncode from dart::convert
Related
An API gives me json response like this:
[{"version": "v3.5"}, {"setup": true}, {"address": "e7d398b"}, {"connected": true}, {"active": true}, {"id": "ce7143"}, {"genuine": true}]
As you can see, this is a list of objects. I tried parsing it like this using quicktype generated model class-
List<Result>.from(result.map((x) => Result.fromJson(x)));
But it's failing since each of the objects are of different types.
I think I have to convert each of the objects in the array one by one to Dart classes and add it to an Array.
So I tried this (I am using dio) -
final result = response.data;
var b = List.empty(growable: true);
result.map((x) => b.add(x));
But it's not working.
How can I atleast access the elements of the array?
Solved
Inspired by the accepted answer, I was able to generate corresponding Dart Class. Never thought can looping through a map is possible, IDE was not giving any clue.
final result = response.data;
Map<String, dynamic> map = {};
for (var e in result) {
map.addAll(e);
}
final finalResult = Result.fromJson(map);
return finalResult;
As Randal Schwartz mentioned above, there is no JSON you can not parse with Dart.
In your case, you have a List of Map objects. What you can do is:
final data = jsonDecode(json) as List;
Map<String, dynamic> map = {};
for (var e in data) {
map.addAll(e);
}
print(map);
//prints
{version: v3.5, setup: true, address: e7d398b, connected: true, active: true, id: ce7143, genuine: true}
If you're using the dio flutter package it returns decoded json, no
need to call for jsonDecode.
I recommend using json code generation if you face large json instead of relying on quicktype generated models.
There's no JSON that isn't parsable with Dart. But you might end up with a data structure that requires careful navigation. Classes make it easier, but there isn't always a class structure for any arbitrary JSON, and maybe that's your point. In that case, you'll have to navigate to the data of interest in an ad-hoc fashion.
I copied this code from somewhere online that said that it is good to use a model for your data interfacing. I've used the fromJson function a lot so far, but never the toJson function since anytime I need to write data to Firebase the built-in functions let me write in the JSON right then and there. When should I be using this toJson and how would I use it?
ModelFriend.fromJson(Map<dynamic, dynamic>? json): //Transform JSON into model
createDate = json?['createDate'] as String,
modifiedDate = json?['modifiedDate'] as String,
stat = json?['stat'] as String,
uid = json?['uid'] as String,
username = json?['username'] as String;
Map<dynamic, dynamic> toJson() => <dynamic, dynamic>{ //Transforms model into JSON
'createDate': createDate,
'modifiedDate': modifiedDate,
'stat': stat,
'uid': uid,
'username': username,
};
When we want to add documents to Cloud Firestore in Flutter, we can use the following code:
await firestore.doc(documentPath).set(data);
The type of the data variable is Map<String, dynamic>, so you need to convert the model to a map like this:
final Model model = Model(
name,
email,
);
await firestore.doc(documentPath).set(model.toJson());
Also, if you use the code below, you may enter the wrong field and get an error:
await firestore.doc(documentPath).set({
"naem": name, // Typo, "name" becomes "naem"
"email": email,
});
So, the answer is, we need toJson to convert the model to a map and add it to Cloud Firestore.
An API is giving me a JSON response like so :
{
"amountCredited":0,
"isFirstOrder":false,
"orderItems":[
{
"_id":624342e1c66be9001d501230,
"status":2,
"pinCode":749326,
"kioskId":61bb3982089a66001db4ab77,
"kioskActivityId":620668ad433322b99557c874
}
]
}
I'm trying to access the data inside the "orderItems" in order to feed it to an existing parsing model in the App
order = OrderItemModel.fromJson(response.body['orderItems'] as Map<String, dynamic>);
but since the data inside orderItems JSON response is inside an array I can't access it this way..
How can I access it knowing that this JSON "orderItems" array will always only have one item as a response ?
Would something like response.body['orderItems' : [0]] enable me to access the first item data ?
Since you always know that the array will always have only one item. We'll first make it a List & then access the first element.
order = OrderItemModel.fromJson((response.body['orderItems'] as List<dynamic>).first as Map<String, dynamic>);
To understand it a bit better refer to the code below:
The JSON response contains an array, which we need to access.
final ordersArray = response.body['orderItems'] as List<dynamic>;
Then we want to access the first order (according to the question)
final firstOrder = ordersArray.first as Map<String, dynamic>;
Once we have the order, we'll convert it to the model
final order = OrderItemModel.fromJson(firstOrder);
EDIT:
as it was pointed out in a comment List objects have a getter called first which can be used to get the first element, the code has been updated with that.
You need to convert as Map and List because Flutter deal only with this datatypes. For example:
Map order1 = {
"_id":"624342e1c66be9001d501230",
"status":2,
"pinCode":749326,
"kioskId":"61bb3982089a66001db4ab77",
"kioskActivityId":"620668ad433322b99557c874"
};
Map order2 = {
"_id":"224342e1c66be9001d501232",
"status":1,
"pinCode":248023,
"kioskId":"41bb3982089a66001db4ab74",
"kioskActivityId":"720668ad433322b99557c875"
};
Map m = {
"amountCredited":0,
"isFirstOrder":false,
"orderItems":[
order1,
order2
]
};
print(m['orderItems'][1]);
print(m['orderItems'][1]['pinCode']);
The result will be:
{_id: 224342e1c66be9001d501232, status: 1, pinCode: 248023, kioskId: 41bb3982089a66001db4ab74, kioskActivityId: 720668ad433322b99557c875}
248023
In my app, the user chooses the chapter he wants to read, the verse he wants to begin from, and the end verse.
I'm going to store these three strings and show in his "reading history" list, where he can see all of his previous readings.
I read that you can do that by creating a class, storing these in an object and converting it to JSON then storing it inside sharedprefs.(or something like that).
But I didn't understand them as they were a little different from my case.
this is the class:
class Segment {
final String chapter;
final String from;
final String to;
Segment({this.chapter, this.from, this.to});
factory Segment.fromJson(Map<String, dynamic> json) {
return Segment(
chapter: json['chapter'],
from: json['from'],
to: json['to'],
);
}
Map<String, dynamic> toJson() {
return {
'chapter': chapter,
'from': from,
'to': to,
};
}
}
these the steps i want to know how to do:
store the string in the object.
Encode the object to JSON.
store it inside sharedprefs.
decode it back and choose a certain item from the list.
You can store a JSON (Map) object with shared preferences in Flutter by encoding the Map to raw JSON (it is basically a String).
To store something with shared preferences you should first of all add it to your dependencies. Here's how.
Then somewhere in your code get the instance of SharedPreferences object by doing:
final prefs = await SharedPreferences.getInstance();
After that you should encode the Map that you got from your Segment class by doing this:
Segment segment = Segment(...);
String rawJson = jsonEncode(segment.toJson());
To save this new JSON with shared preferences run this command to store the whole JSON as a String:
prefs.setString('my_string_key', rawJson);
When you want to read your data from shared preferences use this:
final rawJson = prefs.getString('my_string_key') ?? '';
Map<String, dynamic> map = jsonDecode(rawJson);
final Segment = Segment.fromJson(map);
For more details see this article.
From my REST API a JSON string is received as
{"total":"30","results":[
{"ID":"1809221034017","DATE":"2018-09-22","REG":"(E9)","START":"10:40","END":"10:48"},
{"ID":"1809221337250","DATE":"2018-09-22","REG":"(E4)","START":"13:43","END":"13:57"},
{"ID":"1809161032213","DATE":"2018-09-16","REG":"(E1)","START":"11:04","END":"11:13"}]}
The total field tells me that the database contains in total 30 records, the requested data (only 3 rows) is included in the results section.
I need to parse the data, so I can show the results in ListView. I managed to do this with a simple JSON string, but not with this complex JSON string. Unfortunately I am not able to change the output of the web service since this is hosted by a 3rd party.
Any help, or a code example, is appreciated.
Thanks in advance
Read first my other answer here.
Then I suggest you to use a class generation library like quicktype.
Using quick type for example you can easily and automatically genearate your moidel class in dart using your JSON. Here the generated file.
quicktype --lang dart --all-properties-optional https://www.shadowsheep.it/so/53968769/testjson.php -o my_json_class.dart
Then use it in code:
import 'my_json_class.dart';
import 'package:http/http.dart' as http;
var response = await http.get('https://www.shadowsheep.it/so/53968769/testjson.php');
var myClass = MyJsonClass.fromJson(jsonDecode(response.body));
for(var result in myClass.results.toList()) {
print(result?.id);
}
N.B. If you'll master a code generator library, then you'll be able to parse any type of JSON coming from a REST API and you'll have more time for fun.
So here we can see that there is a JSON object having two values a JSON array and a total number.Sometimes the internet services don't return the full value but only a part due to network issues.
So now in the array we have number of results objects with an ID,DATE,REG,START,END.
If you format the JSON you will decode it easily.
i recommend this article: https://medium.com/flutter-community/parsing-complex-json-in-flutter-747c46655f51
class Result
{
String id ;
String date;
String reg ;
String start;
String end ;
Result({this.date,this.end,this.id,this.reg,this.start});
factory Result.fromJson(Map<String, dynamic> parsedJson) {
return new Result(
id: parsedJson['ID'],
date: parsedJson['DATE'],
reg: parsedJson['REG'],
start: parsedJson['START'],
end: parsedJson['END'],
);
}
}
class Results
{
String total;
List<Result> results;
Results({this.results, this.total});
factory Results.fromJson(Map<String, dynamic> parsedJson) {
var list = parsedJson['results'][] as List;
return new Results(
total: parsedJson['total'],
results: list.map((i) => Result.fromJson(i)).toList());
}}