How to check for NULL when mapping nested JSON?

前端 未结 2 883
栀梦
栀梦 2021-01-12 08:13

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

相关标签:
2条回答
  • 2021-01-12 08:51

    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.

    0 讨论(0)
  • 2021-01-12 08:54

    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.

    0 讨论(0)
提交回复
热议问题