Add support for `fromJson()` methods on container types
Community Note
Please vote by adding a 👍 reaction to the issue to help us prioritize. If you are interested to work on this issue, please leave a comment.
Feature Spec
implemented for primitives in: https://github.com/winglang/wing/pull/1768
https://docs.winglang.io/reference/spec#1146-schema-validation
let j = Json [1, 2, 3];
let a = Array<num>.fromJson(j);
```
### Use Cases
Allows us to parse container types safely from Json at runtime.
### Implementation Notes
The implementation here is not trivial as we need to ensure that in any given Json container type (ie. Map, Array) that the entries are homogenous and match the expected type. Our Json types allow for heterogenous arrays so just verifying a single index is not sufficient. There needs to be O(n) checks where n is the number of entries in the Json container.
Note: Should append example in language reference 1.1.4.5 to contain:
```TS
let myArray = Json [1,2,3,"hello"];
Array<num>.fromJson(myArray); // RUNTIME ERROR: unable to parse `[1,2,3,"hello"]` as an array of `num`.
Component
SDK
@hasanaburayyan - can you please add some implementation notes on why this is not trivial? I believe you said it has to do with type checking (for homogenous arrays, etc.), right?
Hi,
This issue hasn't seen activity in 60 days. Therefore, we are marking this issue as stale for now. It will be closed after 7 days. Feel free to re-open this issue when there's an update or relevant information to be added. Thanks!
Is there a workaround to get an Array object from a generic Json?
@skorfmann I cant think of a workaround off the top of my head. However I can probably wip up a solution for this using a macro real quick it might not be efficient or optimal but it would enable uses to extract container types from Json. @staycoolcall911 any thoughts?
@skorfmann I think you should be able to parse the json using extern js code.
Let me know if that doesn't work for you or if it turns out too ugly and we'll bump this issue to p1.
@skorfmann I think you should be able to parse the json using
externjs code. Let me know if that doesn't work for you or if it turns out too ugly and we'll bump this issue to p1.
Was just curious if there's a workaround in Wing itself. Not urgent, since doing this in JS land will do for now.
Hi,
This issue hasn't seen activity in 90 days. Therefore, we are marking this issue as stale for now. It will be closed after 7 days. Feel free to re-open this issue when there's an update or relevant information to be added. Thanks!
Another way to solve this will be to add tryAsArray, tryAsStruct,tryAsMap, tryAsMap macros to Json and mutJson (when the type is validated in the macro itself), it's definitely an easier approach, but will it be enough @Chriscbr ?
Not sure how much value it adds, but adding this here, I was trying to understand how to do this and got it working with the hacky workaround.
pub inflight getFriends(id:str): MutArray<types.Friend>? {
let data = this.table.query(
KeyConditionExpression: "PK = :spaceID AND begins_with(SK, :friendId)",
ExpressionAttributeValues: {
":spaceID": "SPACE#{id}",
":friendId": "FRIEND_ID"
},
);
let friends = MutArray<types.Friend>[];
if (data.Count == 0) {
return friends;
}
for item in data.Items {
friends.push(types.Friend.fromJson(item));
}
return friends;
}
I'm all for let a = Array<num>.fromJson(j);!