Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add new sample with domain model classes and JSON serialization #10

Closed
navibyte opened this issue Aug 10, 2021 · 1 comment
Closed

Add new sample with domain model classes and JSON serialization #10

navibyte opened this issue Aug 10, 2021 · 1 comment
Labels
enhancement New feature or request 🗒️ attributes Related to the code package "attributes"

Comments

@navibyte
Copy link
Collaborator

navibyte commented Aug 10, 2021

import 'package:attributes/data.dart';

void main() {
  _decodeSampleData();
}

/// [Address] is a simple data object 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});

  factory 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 Smith",
///     "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});

  factory 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] is a data array with a list of [Person] data objects.
///
/// Sample source data as a JSON Array:
/// ```json
///   [
///     {
///       "name": "John Smith",
///       "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});

  factory PersonCollection.fromData(DataArray data) => PersonCollection(
        persons: data.objects
            .map((element) => Person.fromData(element))
            .toList(growable: false),
      );

  DataArray toData() => DataArray.of(
        persons.map((person) => person.toData()).toList(growable: false),
      );
}

void _decodeSampleData() {
  // Some json data as JSON Array.
  const jsonData = '''
  [
     { 
       "name": "John Smith",
       "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());
}
@navibyte
Copy link
Collaborator Author

Implemented in BETA-version 0.7.0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request 🗒️ attributes Related to the code package "attributes"
Projects
None yet
Development

No branches or pull requests

0 participants