denormalizeFragment function

Map<String, dynamic>? denormalizeFragment(
  1. {required Map<String, dynamic>? read(
    1. String dataId
    ),
  2. required DocumentNode document,
  3. required Map<String, dynamic> idFields,
  4. String? fragmentName,
  5. Map<String, dynamic> variables = const {},
  6. Map<String, TypePolicy> typePolicies = const {},
  7. DataIdResolver? dataIdFromObject,
  8. bool addTypename = false,
  9. bool returnPartialData = false,
  10. bool handleException = true,
  11. bool allowDanglingReference = false,
  12. String referenceKey = kDefaultReferenceKey,
  13. Map<String, Set<String>> possibleTypes = const {}}
)

Denormalizes data for a given fragment.

Pass in a read function to read the normalized map.

An idFields Map must be provided that includes all identifying data, per any pertinent TypePolicy or dataIdFromObject funciton. If entities of this type are simply identified by their __typename & id fields, you can simply provide a map with just the id field (i.e. { "id": "1234" }).

If any TypePolicys or a dataIdFromObject function were used to normalize the data, they must be provided to ensure that the appropriate normalized entity can be found.

Likewise, if a custom referenceKey was used to normalize the data, it must be provided. Otherwise, the default '$ref' key will be used.

Implementation

Map<String, dynamic>? denormalizeFragment({
  required Map<String, dynamic>? Function(String dataId) read,
  required DocumentNode document,
  required Map<String, dynamic> idFields,
  String? fragmentName,
  Map<String, dynamic> variables = const {},
  Map<String, TypePolicy> typePolicies = const {},
  DataIdResolver? dataIdFromObject,
  bool addTypename = false,
  bool returnPartialData = false,
  bool handleException = true,
  bool allowDanglingReference = false,
  String referenceKey = kDefaultReferenceKey,
  Map<String, Set<String>> possibleTypes = const {},
}) {
  if (addTypename) {
    document = transform(
      document,
      [AddTypenameVisitor()],
    );
  }
  final fragmentMap = getFragmentMap(document);
  final fragmentDefinition = findFragmentInFragmentMap(
    fragmentMap: fragmentMap,
    fragmentName: fragmentName,
  );

  final dataId = resolveDataId(
    data: {
      '__typename': fragmentDefinition.typeCondition.on.name.value,
      ...idFields,
    },
    typePolicies: typePolicies,
    dataIdFromObject: dataIdFromObject,
  );

  if (dataId == null) {
    throw Exception(
      'Unable to resolve data ID for type ${fragmentDefinition.typeCondition.on.name.value}. Please ensure that you are passing the correct ID fields',
    );
  }

  final config = NormalizationConfig(
    read: read,
    variables: variables,
    typePolicies: typePolicies,
    referenceKey: referenceKey,
    fragmentMap: fragmentMap,
    dataIdFromObject: dataIdFromObject,
    addTypename: addTypename,
    allowPartialData: returnPartialData,
    allowDanglingReference: allowDanglingReference,
    possibleTypes: possibleTypes,
  );

  try {
    return denormalizeNode(
      selectionSet: fragmentDefinition.selectionSet,
      dataForNode: read(dataId),
      config: config,
    ) as Map<String, dynamic>?;
  } on PartialDataException {
    if (handleException) {
      return null;
    }
    rethrow;
  }
}