wing icon indicating copy to clipboard operation
wing copied to clipboard

Add support for `fromJson()` methods on container types

Open hasanaburayyan opened this issue 2 years ago • 9 comments

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 avatar Mar 13 '23 20:03 hasanaburayyan

@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?

staycoolcall911 avatar Mar 14 '23 09:03 staycoolcall911

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!

github-actions[bot] avatar May 15 '23 06:05 github-actions[bot]

Is there a workaround to get an Array object from a generic Json?

skorfmann avatar Jun 08 '23 19:06 skorfmann

@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?

hasanaburayyan avatar Jun 08 '23 20:06 hasanaburayyan

@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.

staycoolcall911 avatar Jun 09 '23 06:06 staycoolcall911

@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.

Was just curious if there's a workaround in Wing itself. Not urgent, since doing this in JS land will do for now.

skorfmann avatar Jun 09 '23 13:06 skorfmann

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!

github-actions[bot] avatar May 31 '24 06:05 github-actions[bot]

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 ?

tsuf239 avatar Aug 07 '24 11:08 tsuf239

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);!

boyney123 avatar Sep 16 '24 13:09 boyney123