Json string to Dictionary

Hi all,

Unless I'm mistaken, there is no builtin class or function to do it. For the need of my widget (APICall), I coded a function to do it.
I'm not a professionnal developper, so it surely not perfect but do the job.

I followed this description of the grammar : www.json.org/json-fr.html.
But do some minor changes :
- The "name" part of an objet can be defined without "double quote" if start with a letter and have only letter, digit, -, _ or . Ex : {name:"value"} is ok.
- It only accept space as "whitespace", no tab, carrier return etc ... but you can change the function <read_spaces> to change this behavior.
- It accept there is not "whitespace" beetween any element of the grammar.
- It doesn't correctly interprete some escaped characters in a string (\\, \/ and \" are OK, but \b \f \n \r \t and \u are not interpreted).

It's only a set of functions not a class. You just have to call json_to_dict(my_json_str_convert). It will return a dictionnary.
If there is a syntax error, it only return null, it is perhaps the main improvement to do ;o)

Enjoy !

Source code here : https://apicall.dumesnil.net/APICallJson.html

  • JSON returned from makeWebRequest is converted into dictionary form for you.

  • If you are using makeWebRequest to get the data with

    responseType => Comm.HTTP_RESPONSE_CONTENT_TYPE_JSON

    You'll see the data as a dictionary.

  • Hi know,
    but my widget need too many parameters, so I ask the user to group it as a json. So I use it to :

    - read the parameters from users

    - and be able to push POST parameters as a dict to makeWebRequest() (the user give me a string from setting also).

    ;o)

  • Not sure I'd ever want a user to enter a json string for settings.  Worst case, maybe a comma separated string, maybe with some boolean or number fields to add some specifics.  Easier to parse.  

    Or allow configuration by way of a menu in your widget.

  • -

    I re-formatted your post to use code tags. Unfortunately read_number won't post, so I'm posting a slightly modified version of it separately here.

    enum {
        NUMBER,
        FLOAT
    }
    
    function read_number(p_str, it) {
        var it_b = it; // begin
        var type = NUMBER;
        var ret_number = null;
    
        if (it < p_str.length() && (p_str.substring(it, it + 1).equals("-") || p_str.substring(it, it + 1).toNumber() != null)) { // Start with - or digit
            while (it < p_str.length()) {
                var tmp_char = p_str.substring(it, it + 1);
                if (tmp_char.toNumber() != null || tmp_char.equals("-") || tmp_char.equals("+") || tmp_char.equals(".") || 
                    tmp_char.equals("e") || tmp_char.equals("E")) {
                    if (tmp_char.equals(".") || tmp_char.equals("e") || tmp_char.equals("E")) {
                        type = FLOAT;
                    }
                    it++;
                } else {
                    break;
                }
            }
    
            if (type == FLOAT) {
                ret_number = p_str.substring(it_b, it).toFloat();
            } else {
                ret_number = p_str.substring(it_b, it).toNumber();
            }
            if (ret_number != null) {
                return [ret_number, it];
            }
        }
        return null;
    }

  • It might not be a good idea to rewrite a JSON parser.

    Use something easier for the user to enter.

    Some people have written a program running on a PC/phone to create these sorts of parameter strings.

  • ... you are right, for large public apps, or for an app with a quite few parameters (<100), it's not appropiate.

    But let me expose my widget :

    APICall is a widget to call APIs, so not for all people but people that understand quite well what is a json. More, I want the user to be able to configure 36 url, with a name, an icon, a POST content, the json name to get to be displayed as a result, a group name, an icon for the group name, an option to autolaunch, another to auto pass to the next action ... you are above the 300 settings ...

    Yes there are surely best ways to do (a beautifull compagnion app ?), but anyway this thread is not to discuss about the usage in my app, simply to share something that can perhaps helps someone Wink

  • Maybe, have the user indicate a URL to the json configuration stuff.

  • One other thing to consider here is with a large amount of data in app settings, that will increase the peak memory if your widget is running when settings are changed.  Even if you don't use the new settings.

  • Yes, that is also why I prefer a json that defines only options that are used, instead of hundred of settings that are not mandatory. Honeslty, the memory is a 'problem' only for some watches that have only 60K, but I take care to optimize the code and it seems to be OK.

    No, the issue is more that parsing a json require many actions, and actually, if there is too many complex json I get the Error: 'Watchdog Tripped Error - Code Executed Too Long' Sweat smile