cancel
Showing results forย 
Search instead forย 
Did you mean:ย 

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

ddangler
New Contributor III

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)

4 REPLIES 4

tstack
Former Employee

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]) }), "$*")

ddangler
New Contributor III

@tstack,

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

Selection_463

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]) }), "$*")

ddangler
New Contributor III

I appreciate the prompt response and it worked. You saved me again ๐Ÿ™‚