deserialize method

  1. @override
Future<DeserializedData<T>> deserialize(
  1. Object? data
)
inherited

Returns a DeserializedData object when deserializing a given data.

Implementation

@override
Future<DeserializedData<T>> deserialize(Object? data) async {
  final result = DeserializedData<T>([], included: []);

  Future<Object?> _processIdAndAddInclude(id, RemoteAdapter? adapter) async {
    if (id is Map && adapter != null) {
      final data = await adapter.deserialize(id as Map<String, dynamic>);
      result.included
        ..add(data.model as DataModelMixin<DataModelMixin>)
        ..addAll(data.included);
      id = data.model!.id;
    }
    if (id != null && adapter != null) {
      return graph.getKeyForId(adapter.internalType, id,
          keyIfAbsent: DataHelpers.generateKey(adapter.internalType));
    }
    return null;
  }

  if (data == null || data == '') {
    return result;
  }

  if (data is Map<String, dynamic>) {
    data = [data];
  }

  if (data is Iterable) {
    for (final map in data) {
      final mapIn = Map<String, dynamic>.from(map as Map);
      final mapOut = <String, dynamic>{};

      final relationships = localAdapter.relationshipMetas;

      // - process includes
      // - transform ids into keys to pass to the local deserializer
      for (final mapKey in mapIn.keys) {
        final metadata = relationships[mapKey];

        if (metadata != null) {
          final relType = metadata.type;

          if (metadata.serialize == false) {
            continue;
          }

          if (metadata.kind == 'BelongsTo') {
            final key = await _processIdAndAddInclude(
                mapIn[mapKey], adapters[relType]!);
            if (key != null) mapOut[mapKey] = key;
          }

          if (metadata.kind == 'HasMany') {
            mapOut[mapKey] = [
              for (final id in (mapIn[mapKey] as Iterable))
                await _processIdAndAddInclude(id, adapters[relType]!)
            ].filterNulls;
          }
        } else {
          // regular field mapping
          mapOut[mapKey] = mapIn[mapKey];
        }
      }

      final model = localAdapter.deserialize(mapOut);
      result.models.add(model);
    }
  }

  return result;
}