DEV Community

Khoa Pham
Khoa Pham

Posted on

How to resolve deep json object in Dart

If we are not on the edge with GRPC and Protocol Buffer, then most likely we are going to deal with Restful and JSON. In one of my Flutter apps I needed to consume JSON

JSON and serialization

The guide at https://flutter.dev/docs/development/data-and-backend/json is definitely the way to go.

Currently there are 2 ways. One is to manually use dart:convert package

Map<String, dynamic> user = jsonDecode(jsonString);
Enter fullscreen mode Exit fullscreen mode

The other way is to use json_serializable to generate parsing code

import 'package:json_annotation/json_annotation.dart';

/// This allows the `User` class to access private members in
/// the generated file. The value for this is *.g.dart, where
/// the star denotes the source file name.
part 'user.g.dart';

/// An annotation for the code generator to know that this class needs the
/// JSON serialization logic to be generated.
@JsonSerializable()

class User {
  User(this.name, this.email);

  String name;
  String email;

  /// A necessary factory constructor for creating a new User instance
  /// from a map. Pass the map to the generated `_$UserFromJson()` constructor.
  /// The constructor is named after the source class, in this case User.
  factory User.fromJson(Map<String, dynamic> json) => _$UserFromJson(json);

  /// `toJson` is the convention for a class to declare support for serialization
  /// to JSON. The implementation simply calls the private, generated
  /// helper method `_$UserToJson`.
  Map<String, dynamic> toJson() => _$UserToJson(this);
}
Enter fullscreen mode Exit fullscreen mode

json_resolve

The problem with manual approach is that it involves lot of boilerplate code, especially when accessing property inside deeply nested json. The problem with code generation approach is that it does not always fit our need and may lack of customization.

Therefore I created json_resolve which allows us to access json using keypath, with type checking and safety in mind. The code is small, simple to reason and tested.

final String byProperty = resolve(json: json, path: "movie", defaultValue: "error");
expect(byProperty, "isFun");

final int byInt = resolve(json: json, path: "earth", defaultValue: 0);
expect(byInt, 199999);

final String byIndex = resolve(json: json, path: "dc.2.name", defaultValue: "error");
expect(byIndex, "Wonder Woman");

final String byIndexThenProperty = resolve(json: json, path: "marvel.0.appear.1.title", defaultValue: "error");
expect(byIndexThenProperty, "The Dark World");
Enter fullscreen mode Exit fullscreen mode

Original post https://github.com/onmyway133/blog/issues/198

Top comments (2)

Collapse
 
kpaxian profile image
Alexander Mazuruk

I'd recommend to use my library for that github.com/k-paxian/dart-json-mapper

Collapse
 
nonoyek profile image
nonoyek

thankss this save a lots of time! :D