maybeFromDynamic static method
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
.
{ "type":
Implementation
static JsonWidgetData? maybeFromDynamic(
dynamic map, {
JsonWidgetRegistry? registry,
}) {
JsonWidgetData? result;
registry ??= JsonWidgetRegistry.instance;
if (map is JsonWidgetData) {
result = map;
} else if (map != null) {
try {
final type = map['type'];
final timer = ExecutionWatch(
group: 'JsonWidgetData.fromDynamic',
name: type,
precision: TimerPrecision.microsecond,
).start();
try {
if (type is! String) {
throw HandledJsonWidgetException(
'Unknown type encountered: [$type]',
data: map,
);
}
final builder = registry.getWidgetBuilder(type);
final args = map['args'] as Map? ?? const {};
final jsonWidgetListenVariables = _getListenVariables(map);
// The validation needs to happen before we process the dynamic args
// orelse there may be non-JSON compatible objects in the map which
// will always fail validation.
if (kDebugMode) {
registry.validateBuilderSchema(
type: type,
value: args,
validate: map.containsKey('args') ? true : false,
);
}
result = JsonWidgetData(
jsonWidgetArgs: map['args'] ?? {},
jsonWidgetBuilder: () {
return builder(
args,
registry: registry,
);
},
jsonWidgetListenVariables: jsonWidgetListenVariables,
jsonWidgetId: map['id'],
jsonWidgetRegistry: registry,
jsonWidgetType: type,
);
} finally {
timer.stop();
}
} catch (e, stack) {
if (e is HandledJsonWidgetException) {
rethrow;
}
var errorValue = map;
if (errorValue is Map || errorValue is List) {
errorValue = const JsonEncoder.withIndent(' ').convert(errorValue);
}
if (e is AssertionError) {
throw HandledJsonWidgetException(
e,
data: errorValue,
);
} else {
_logger.severe(
'''
*** WIDGET PARSE ERROR ***
$errorValue
''',
e,
stack,
);
}
throw HandledJsonWidgetException(
e,
data: errorValue,
stackTrace: stack,
);
}
}
return result;
}