Skip to content

Samples to compare using fromJson/toJson and using data objects provided by the attributes package #15

@navispatial

Description

@navispatial

See sample for previous version Add new sample with domain model classes and JSON serialization #10.

These samples included in the release version 0.8.0.

A sample using attributes package

import 'package:attributes/data.dart';

void main() {
  _decodeSampleData();
}

/// [Address] model with [street] and [city] fields.
///
/// Sample source data as a JSON Object:
/// `{ "street": "Main street", "city": "Anytown" }`
class Address {
  final String street;
  final String city;

  const Address({required this.street, required this.city});

  static Address fromData(DataObject data) => Address(
        street: data.getString('street'),
        city: data.getString('city'),
      );

  DataObject toData() => DataObject.of({
        'street': street,
        'city': city,
      });
}

/// [Person] with [name], [age], an optional [length] and aggregated [address].
///
/// Sample source data as a JSON Object:
/// ```json
///   {
///     "name": "John Doe",
///     "age": 52,
///     "length": 1.75,
///     "address": { "street": "Main street", "city": "Anytown" },
///     "updated": "2021-08-09 09:00Z"
///   }
/// ```
class Person {
  final String name;
  final int age;
  final double? length;
  final Address address;
  final DateTime updatedUTC;

  const Person(
      {required this.name,
      required this.age,
      this.length,
      required this.address,
      required this.updatedUTC});

  static Person fromData(DataObject data) => Person(
      name: data.getString('name'),
      age: data.getInt('age'),
      length: data.tryDouble('length'),
      address: Address.fromData(data.object('address')),
      updatedUTC: data.getTimeUTC('updated'));

  DataObject toData() => DataObject.of({
        'name': name,
        'age': age,
        if (length != null) 'length': length,
        'address': address.toData(),
        'updated': updatedUTC,
      });
}

/// [PersonCollection] model with a list of [Person] model objects.
///
/// Sample source data as a JSON Array:
/// ```json
///   [
///     {
///       "name": "John Doe",
///       "age": 52,
///       "length": 1.75,
///       "address": { "street": "Main street", "city": "Anytown" },
///       "updated": "2021-08-09 09:00Z"
///     }
///   ]
/// ```
class PersonCollection {
  final Iterable<Person> persons;

  const PersonCollection({required this.persons});

  static PersonCollection fromData(DataArray data) =>
      PersonCollection(persons: data.objectsToList(Person.fromData));

  DataArray toData() =>
      DataArray.from<Person>(persons, (person) => person.toData());
}

void _decodeSampleData() {
  // Some json data as JSON Array.
  const jsonData = '''
  [
     { 
       "name": "John Doe",
       "age": 52,
       "length": 1.75,
       "address": { "street": "Main street", "city": "Anytown" },
       "updated": "2021-08-09 09:00Z"
     }
  ]
  ''';

  // Decode JSON using DataArray.
  final decoded = DataArray.decodeJson(jsonData);

  // Map decoded objects to the domain model objects.
  final personCollection = PersonCollection.fromData(decoded);

  // Use domain objects, here just print names and address info.
  for (final person in personCollection.persons) {
    print('${person.name} lives in ${person.address.street}');
  }

  // JSON data encoded from domain objects and outputted
  print(personCollection.toData().encodeJson());
}

A sample NOT using attributes package

import 'dart:convert';

void main() {
  _decodeSampleData();
}

/// [Address] model with [street] and [city] fields.
///
/// Sample source data as a JSON Object:
/// `{ "street": "Main street", "city": "Anytown" }`
class Address {
  final String street;
  final String city;

  const Address({required this.street, required this.city});

  static Address fromJson(Map<String, dynamic> json) => Address(
        street: json['street'] as String,
        city: json['city'] as String,
      );

  Map<String, dynamic> toJson() => <String, dynamic>{
        'street': street,
        'city': city,
      };
}

/// [Person] with [name], [age], an optional [length] and aggregated [address].
///
/// Sample source data as a JSON Object:
/// ```json
///   {
///     "name": "John Doe",
///     "age": 52,
///     "length": 1.75,
///     "address": { "street": "Main street", "city": "Anytown" },
///     "updated": "2021-08-09 09:00Z"
///   }
/// ```
class Person {
  final String name;
  final int age;
  final double? length;
  final Address address;
  final DateTime updatedUTC;

  const Person(
      {required this.name,
      required this.age,
      this.length,
      required this.address,
      required this.updatedUTC});

  static Person fromJson(Map<String, dynamic> json) => Person(
      name: json['name'] as String,
      age: json['age'] as int,
      length: json['length'] as double?,
      address: Address.fromJson(json['address'] as Map<String, dynamic>),
      updatedUTC: DateTime.parse(json['updated'] as String).toUtc());

  Map<String, dynamic> toJson() => <String, dynamic>{
        'name': name,
        'age': age,
        if (length != null) 'length': length,
        'address': address.toJson(),
        'updated': updatedUTC.toIso8601String(),
      };
}

/// [PersonCollection] model with a list of [Person] model objects.
///
/// Sample source data as a JSON Array:
/// ```json
///   [
///     {
///       "name": "John Doe",
///       "age": 52,
///       "length": 1.75,
///       "address": { "street": "Main street", "city": "Anytown" },
///       "updated": "2021-08-09 09:00Z"
///     }
///   ]
/// ```
class PersonCollection {
  final Iterable<Person> persons;

  const PersonCollection({required this.persons});

  static PersonCollection fromJson(Iterable<dynamic> json) => PersonCollection(
        persons: json
            .map<Person>((dynamic element) =>
                Person.fromJson(element as Map<String, dynamic>))
            .toList(growable: false),
      );

  List<dynamic> toJson() => persons
      .map<Map<String, dynamic>>((person) => person.toJson())
      .toList(growable: false);
}

void _decodeSampleData() {
  // Some json data as JSON Array.
  const jsonData = '''
  [
     { 
       "name": "John Doe",
       "age": 52,
       "length": 1.75,
       "address": { "street": "Main street", "city": "Anytown" },
       "updated": "2021-08-09 09:00Z"
     }
  ]
  ''';

  // Decode JSON and cast it to `Iterable<Object?>`.
  final decoded = json.decode(jsonData) as Iterable<dynamic>;

  // Map decoded objects to the domain model objects.
  final personCollection = PersonCollection.fromJson(decoded);

  // Use domain objects, here just print names and address info.
  for (final person in personCollection.persons) {
    print('${person.name} lives in ${person.address.street}');
  }

  // JSON data encoded from domain objects and outputted
  print(json.encode(personCollection.toJson()));
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    🗒️ attributesRelated to the code package "attributes"documentationImprovements or additions to documentation

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions