I'm trying to map a nested JSON to the model object, the problem is when it returns null, it will break all the code, I want to check if null do something but not break the app.
THE JSON FILE:
[
{
"id": 53,
"date": "2018-12-28T08:51:11",
"title": {
"rendered": "this is for featured"
},
"content": {
"rendered": "\n<p><g class=\"gr_ gr_3 gr-alert gr_spell gr_inline_cards gr_run_anim ContextualSpelling\" id=\"3\" data-gr-id=\"3\">sdafkj</g> <g class=\"gr_ gr_10 gr-alert gr_spell gr_inline_cards gr_run_anim ContextualSpelling ins-del multiReplace\" id=\"10\" data-gr-id=\"10\">kj</g> <g class=\"gr_ gr_16 gr-alert gr_spell gr_inline_cards gr_run_anim ContextualSpelling ins-del multiReplace\" id=\"16\" data-gr-id=\"16\">asd</g> <g class=\"gr_ gr_18 gr-alert gr_spell gr_inline_cards gr_run_anim ContextualSpelling\" id=\"18\" data-gr-id=\"18\">kadjsfk</g> kljadfklj sd</p>\n",
"protected": false
},
"excerpt": {
"rendered": "<p>sdafkj kj asd kadjsfk kljadfklj sd</p>\n",
"protected": false
},
"author": 1,
"featured_media": 54,
"_links": {
"self": [
{
"href": "https://client.kurd.app/wp-json/wp/v2/posts/53"
}
],
},
"_embedded": {
"author": [
{
"id": 1,
"name": "hooshyar",
}
],
"wp:featuredmedia": [
{
"id": 54,
"source_url": "https://client.kurd.app/wp-content/uploads/2018/12/icannotknow_22_12_2018_18_48_11_430.jpg",
}
]
}
]
CODE FOR MAPPING TO OBJECT:
featuredMediaUrl = map ["_embedded"]["wp:featuredmedia"][0]["source_url"];
The method 'map' was called on null. Receiver: null [0] which sometimes returns null ;
Here is a simple solution:
safeMapSearch(Map map, List keys) {
if (map[keys[0]] != null) {
if (keys.length == 1) {
return map[keys[0]];
}
List tmpList = List.from(keys);
tmpList.removeAt(0);
return safeMapSearch(map[keys[0]], tmpList);
}
return null;
}
use:
featuredMediaUrl = safeMapSearch(map, ["_embedded","wp:featuredmedia",0,"source_url"]);
The function iterates recursively on the map
with the keys supplied in keys
, if a key is missing it will return null
otherwise it will return the value of the last key.
Following my comment I suggest you to use a code generation library to parse JSON
to JSON Models
.
Read this article that explain you how to use (for example) the json_serializable package.
Such libraries takes all the dirty job of generate all the boilerplate code to create your Model classes and they take care of null
values as mandatory or not.
For example if you annotate a class Person like that:
@JsonSerializable(nullable: true)
class Person {
final String firstName;
final String lastName;
final DateTime dateOfBirth;
Person({this.firstName, this.lastName, this.dateOfBirth});
factory Person.fromJson(Map<String, dynamic> json) => _$PersonFromJson(json);
Map<String, dynamic> toJson() => _$PersonToJson(this);
}
with (nullable: true
) the dart class of your model will skip the null value fields.
UPDATE
Because I'm eager of technology I've given quicktype tool (suggested by Christoph Lachenicht) a try with your example.
I've prepared a mock api and a file example.json
providing the JSON you've posted. I've taken only one element, not the array. And you can have a look here example.json.
After installin QuickType I've generate the model class for this json:
quicktype --lang dart --all-properties-optional example.json -o example.dart
Pay attention here to tha cli parameter --all-properties-optional
that create null checks for missing fields.
Map<String, dynamic> toJson() => {
"id": id == null ? null : id,
"date": date == null ? null : date,
"title": title == null ? null : title.toJson(),
"content": content == null ? null : content.toJson(),
"excerpt": excerpt == null ? null : excerpt.toJson(),
"author": author == null ? null : author,
"featured_media": featuredMedia == null ? null : featuredMedia,
"_links": links == null ? null : links.toJson(),
"_embedded": embedded == null ? null : embedded.toJson(),
};
Then I've used the Example class in example.dart
var jsonExampleResponse =
await http.get('https://www.shadowsheep.it/so/53962129/testjson.php');
print(jsonExampleResponse.body);
var exampleClass = exampleFromJson(jsonExampleResponse.body);
print(exampleClass.toJson());
And all went fine.
N.B. Of course when you use this class you have to check if its fields are empty before using them:
print(exampleClass.embedded?.wpFeaturedmedia?.toString());
That's all. I hope to have put you in the rigth direction.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With