-
Notifications
You must be signed in to change notification settings - Fork 3
Description
The use case that drew my attention to json_events is, that I download a large JSON array where I want to process each object in the array one after the other. Loading the whole JSON into memory for parsing is a no-go. I'm new to Dart/Flutter (coming mainly from C#, C++, Python, Ruby) so I was little bit surprised there was no streaming JSON parser (I'm so used to JSON.Net, I'm probably a little bit spoiled :-) So: json_events to the rescue! (Thanks for providing this!)
But using the JsonArrayTraverser / JsonObjectTraverser feels a little "bulky". Wouldn't it be nice, if you could simply get Map<string, dynamic> objects from a JSON-Stream with an array? Then json_serializable can be used to get the objects from it.
I did a quick test, if this is possible - see code below. (That's where I stumbled upon the other issues, I just posted).
Wouldn't something like this be a nice addition to json_events? If you like this idea, I can try to provide a PR for this. The code below is not yet complete. e.g. an array of arrays wouldn't work. So this would need a little bit more time to do it right with unit tests etc..
readJsonObjectAsMap(StreamIterator<JsonEvent> streamIterator) async {
Queue<dynamic> objectStack = Queue<dynamic>();
Map<String, dynamic> root = {};
objectStack.addLast(root);
String? currentProperty;
JsonEvent? lastEvent;
while (objectStack.isNotEmpty) {
await streamIterator.moveNext();
print("${streamIterator.current.type} : ${streamIterator.current.value}");
switch (streamIterator.current.type) {
case JsonEventType.propertyName:
currentProperty = streamIterator.current.value;
break;
case JsonEventType.propertyValue:
if (currentProperty != null) {
objectStack.last[currentProperty] = streamIterator.current.value;
currentProperty = null;
}
break;
case JsonEventType.beginObject:
Map<String, dynamic> newObject = {};
if (currentProperty != null) {
objectStack.last[currentProperty] = newObject;
}
else {
objectStack.last.add(newObject);
}
currentProperty = null;
objectStack.addLast(newObject);
break;
case JsonEventType.endObject:
objectStack.removeLast();
break;
case JsonEventType.beginArray:
List newArray = [];
objectStack.last[currentProperty] = newArray;
currentProperty = null;
objectStack.addLast(newArray);
break;
case JsonEventType.endArray:
objectStack.removeLast();
break;
case JsonEventType.arrayElement:
// There's a bug that null array element is emitted after an object in an array
if (lastEvent?.type != JsonEventType.endObject)
{
objectStack.last.add(streamIterator.current.value);
}
break;
}
lastEvent = streamIterator.current;
}
return root;
}