How to create a JSON array that works for all types(String, number)?

Hi Forum,

I need to create a JSON array by capturing values from the previous snap. Basic requirement is as below:

Input:

[
    {
        "prop1": "abc",
        "prop2": "2",
        "prop3": null
    }
]

Output:

[
    {
        "custom_fields": [
            {
                "id": 1,
                "value": "abc"
            },
            {
                "id": 2,
                "value": 2
            },
            {
            	"id" : 3
            	"value" : null
            }
        ]
    }
]

The JSON array should work for all data types(string, null and number). so I created a simple pipeline with mapping logic as :
JSON.parse('[{"id": 1, "value": '+ $prop1 + '}, {"id": 2, "value": ' + $prop2 + '}, { "id" : 3, "value" : '+ $prop3 +' } ]')

But it throws error

Failure: Unable to parse JSON value, Reason: Unrecognized token ‘abc’: was expecting (‘true’, ‘false’ or ‘null’), Resolution: Please check the format of the JSON value

Here is the sample pipeline:

1_2017_08_16.slp (3.5 KB)

You can use the mapValues() method to iterate over the values of the object and perform the transformation. The result of that operation is still an object, so you’ll need to use the jsonPath() function with a path of ‘$*’ to get the values of the object into an array. So, the following should do what you want to create the “custom_fields” property:

jsonPath($.mapValues((value, key) => { value: value, id: parseInt(key.match(/\d+/)[0]) }), "$*")

@tstack,

Thanks for looking into it. One followup question. When I tried this, it is double quoting even numbers :

Any help on this?

In the arrow function, you’ll probably want to use parseFloat() to attempt to convert the string to a number. If parsing the string fails, a NaN will be returned, so you can use a logical-or operator to fallback to the original value. Here it is in code:

parseFloat(value) || value

Here is the updated expression:

jsonPath($.mapValues((value, key) => { value: parseFloat(value) || value, id: parseInt(key.match(/\d+/)[0]) }), "$*")
1 Like

I appreciate the prompt response and it worked. You saved me again :slight_smile: