mit-cml / appinventor-sources

MIT App Inventor Public Open Source
http://appinventor.mit.edu/appinventor-sources/
Apache License 2.0
1.47k stars 2.05k forks source link

Add json decode/encode blocks to dictionaries drawer #2123

Open ewpatton opened 4 years ago

ewpatton commented 4 years ago

Describe the desired feature

Have blocks in the dictionaries drawer to encode/decode json.

Give an example of how this feature would be used

This would be used to store structured data in files without also needing to bring in a Web component for the serialization. The internal mechanism can still call the corresponding Web methods to prevent code reuse.

Why doesn't the current App Inventor system address this use case?

Currently, one can do this by including a Web component and using its JsonObjectEncode and JsonTextDecodeWithDictionaries blocks. However, this is not obvious if one is just working with JSON from assets/files. It doesn't make sense to ask users to add a whole unrelated component for the purposes of file I/O.

Why is this feature beneficial to App Inventor's educational mission?

This change would reduce the barrier to entry when working with dictionaries and JSON data. It also provides an analog to the list's to/from csv blocks.

patryk84a commented 4 years ago

You can also add a sort selection when converting. Or sorting as a separate component.

zhangzqs commented 4 years ago

I think it's a great idea to add json decode/encode blocks in dictionaries drawer. And I think the blocks should also be added to list drawer. When we want to decode json data like [1,2,"H",{"name":"Sam","age":22}],we must use json decode block in list drawer. And when we want to decode json data like {"name":"Pater","age":23,"interests":["computer","math","football"]}, we must use json decode block in dictionaries drawer. In other words, we should based on the top type of json data. If user uses json decode/encode blocks by mistake, the system will prompt an error message.

BeksOmega commented 4 years ago

When we want to decode json data like [1,2,"H",{"name":"Sam","age":22}],we must use json decode block in list drawer.

I think that would be a change from the current behavior. If you use list deserialization all objects get deserialized to a list of tuples. For example: blocks (3)

Gives an output of:

["list item 1","list item2",{"key1":"value1","key2":"value2"}]
["list item 1","list item2",[["key1","value1"],["key2":"value2"]]]

Luckily the JsonTextDecodeWithDictionaries works with arrays as well. For example: blocks (4)

Outputs:

["list item 1","list item2",{"key1":"value1","key2":"value2"}]
["list item 1","list item2",{"key1":"value1","key2":"value2"}]

I think this is probably just a result of dictionaries coming later.


My question is: would it also be useful to include the xml decode/encode blocks?

zhangzqs commented 4 years ago

When we want to decode json data like [1,2,"H",{"name":"Sam","age":22}],we must use json decode block in list drawer.

I think that would be a change from the current behavior. If you use list deserialization all objects get deserialized to a list of tuples. For example: blocks (3)

Gives an output of:

["list item 1","list item2",{"key1":"value1","key2":"value2"}]
["list item 1","list item2",[["key1","value1"],["key2":"value2"]]]

Luckily the JsonTextDecodeWithDictionaries works with arrays as well. For example: blocks (4)

Outputs:

["list item 1","list item2",{"key1":"value1","key2":"value2"}]
["list item 1","list item2",{"key1":"value1","key2":"value2"}]

I think this is probably just a result of dictionaries coming later.

My question is: would it also be useful to include the xml decode/encode blocks?

I think we should put decode/encode blocks in dictionaries and lists drawer. For example: (The following platform is Wxbit, which is a powerful platform in China.)

image image

BeksOmega commented 4 years ago

I think we should put decode/encode blocks in dictionaries and lists drawer. For example: image image

Ohhh I get you! Sorry - derrr on my part. I think that's a cool design!

arjuninv commented 3 years ago

If there is going to be both a dictionary from json and list from json block, would the ideal behavior be for these blocks be to throw an error if:

ewpatton commented 3 years ago

More generally, the error should be raised when the type doesn't match what the block expects. Technically, true, "a string", 5 are all valid JSON but clearly not parsable by the proposed blocks if you expect that a dictionary or list should be the result. This was one of the reasons we punted on having built-in blocks for using the web component since there is no expectation of what the return type will be. I think if we go ahead with implementing these blocks an unexpected type should throw an error and in the documentation we recommend that if the type is unknown (e.g., it's coming from a web service), then to use the Web's method instead.

arjuninv commented 3 years ago

That makes perfect sense. Thanks, @ewpatton!