fromDynamic static method

JsonWidgetData? fromDynamic(
  1. dynamic map, {
  2. JsonWidgetRegistry? registry,
})

Decodes a JSON object into a dynamic widget. The structure is the same for all dynamic widgets with the exception of the args value. The args depends on the specific type.

In the given JSON object, only the child or the children can be passed in; not both. From an implementation perspective, there is no difference between passing in a child or a children with a single element, this will treat both of those identically.

{
  "type": <String>,
  "args": <dynamic>,
  "child": <JsonWidgetData>,
  "children": <JsonWidgetData[]>,
  "id": <String>
}

Implementation

static JsonWidgetData? fromDynamic(
  dynamic map, {
  JsonWidgetRegistry? registry,
}) {
  JsonWidgetData? result;
  var innerRegistry = registry ?? JsonWidgetRegistry.instance;

  if (map is String && map.startsWith('{{') && map.endsWith('}}')) {
    var key = map.substring(2, map.length - 2).trim();
    result = DeferredJsonWidgetData(
      key: key,
      registry: innerRegistry,
    );
  } else if (map != null) {
    var type = map['type'];
    var builder = innerRegistry.getWidgetBuilder(type);
    var args = map['args'];

    // The validation needs to happen before we process the dynamic args or
    // else there may be non-JSON compatible objects in the map which will
    // always fail validation.
    assert(innerRegistry.validateBuilderSchema(
      type: type,
      value: args,
      validate: args == null ? false : true,
    ));

    var child = JsonWidgetData.fromDynamic(
      map['child'],
      registry: registry,
    );
    if (type == 'scaffold' && map['args'] is Map && child == null) {
      child = JsonWidgetData.fromDynamic(
        map['args']['body'],
        registry: registry,
      );

      map['args'].remove('body');
    }

    var dynamicParamsResult =
        innerRegistry.processDynamicArgs(args ?? <String, dynamic>{});

    try {
      result = JsonWidgetData(
        args: map['args'] ?? {},
        builder: () {
          return builder(
            innerRegistry
                .processDynamicArgs(args ?? <String, dynamic>{})
                .values,
            registry: registry,
          )!;
        },
        child: child,
        children: JsonClass.fromDynamicList(
          map['children'],
          (dynamic map) => JsonWidgetData.fromDynamic(
            map,
            registry: registry,
          )!,
        ),
        dynamicKeys: dynamicParamsResult.dynamicKeys,
        id: map['id'],
        registry: innerRegistry,
        type: type,
      );
    } catch (e, stack) {
      if (e is _HandledJsonWidgetException) {
        rethrow;
      }
      _logger.severe('Error parsing data:\n$map', e, stack);
      throw _HandledJsonWidgetException(e, stack);
    }
  }

  return result;
}