From 0d1406fe9a843405c664d1c1dac7e76771edc1ae Mon Sep 17 00:00:00 2001 From: Andrew Kolos Date: Wed, 11 Feb 2026 14:08:31 -0800 Subject: [PATCH] fix: parse adjacency-list values for non-root paths In `DataModel.update`, `_parseDataModelContents` was only called when the path was the root. For non-root paths, this caused a TypeError when a widget subscribed to that path expecting a map since the stored value was still the raw A2UI adjacency list format. --- packages/genui/lib/src/model/data_model.dart | 8 ++++++-- packages/genui/test/model/data_model_test.dart | 16 ++++++++++++++++ 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/packages/genui/lib/src/model/data_model.dart b/packages/genui/lib/src/model/data_model.dart index e00fc7298..ee7038fbe 100644 --- a/packages/genui/lib/src/model/data_model.dart +++ b/packages/genui/lib/src/model/data_model.dart @@ -129,9 +129,13 @@ class DataModel { 'DataModel.update: path=$absolutePath, contents=' '${const JsonEncoder.withIndent(' ').convert(contents)}', ); + final Object? parsedContents = contents is List + ? _parseDataModelContents(contents) + : contents; + if (absolutePath == null || absolutePath.segments.isEmpty) { if (contents is List) { - _data = _parseDataModelContents(contents); + _data = parsedContents as Map; } else if (contents is Map) { // Permissive: Allow a map to be sent for the root, even though the // schema expects a list. @@ -151,7 +155,7 @@ class DataModel { return; } - _updateValue(_data, absolutePath.segments, contents); + _updateValue(_data, absolutePath.segments, parsedContents); _notifySubscribers(absolutePath); } diff --git a/packages/genui/test/model/data_model_test.dart b/packages/genui/test/model/data_model_test.dart index a7540bb02..278cdd3a2 100644 --- a/packages/genui/test/model/data_model_test.dart +++ b/packages/genui/test/model/data_model_test.dart @@ -257,6 +257,22 @@ void main() { ]); expect(dataModel.getValue(DataPath('/f')), isNull); }); + + test('parses contents for non-root paths', () { + dataModel.update(DataPath('/todos'), [ + { + 'key': '0', + 'valueMap': [ + {'key': 'id', 'valueString': 'abc'}, + {'key': 'title', 'valueString': 'Buy groceries'}, + ], + }, + ]); + expect( + dataModel.getValue>(DataPath('/todos/0')), + {'id': 'abc', 'title': 'Buy groceries'}, + ); + }); }); });