JSONPATH transformation for arrays


I’m pulling JSON formatted data from an API server with the HTTP binding which delivers back an array of parameters:

{"elements":[{"begin":"2023-01-20T13:00:00+01:00","end":"2023-01-20T14:00:00+01:00","price":18.163},{"begin":"2023-01-20T14:00:00+01:00","end":"2023-01-20T15:00:00+01:00","price":18.236},{"begin":"2023-01-20T15:00:00+01:00","end":"2023-01-20T16:00:00+01:00","price":19.2},... ]}

Based on the documentation, specifically the json-path implementation one can extract specific info from that array in a generic way like $.elements..price which I can use as transformation in the channel of the HTTP binding. I’m not sure, but expect to get a list of the price across all elements. How do I access the individual elements of that list to create items?

Or do I must create one channel and item per element?


If you want to store them in nuber items yes you have to use one channel per number. Try to use $elements[0]…price to get the first Price and than [1] for the second one and so on.

… sure, I can do that. But that is a lot of overhead in creating channels. I was looking to create a single channel with the array transformation with multiple items linked to it while using a 2nd level transformation to pick each element from the JSON list created in the 1st transformation.

How can I observe the output of the transformation on the channel?

Go to the code tab in the thing and copy the channel as often as you need and change the number and the id. I think that is the easiest way

You might be able to get this approach to work using the transform profile. All your Items would be linked to the one Channel and you’d apply a custom transform profile on the link to each individual Item.

However, the “correct” way to model this would be one Channel per value. It’s frankly no less work to add a transformation per link and then if your JSON ever changes, you’ll have a bunch of places to fix it instead of one central place to fix it. It’s the job of the Thing to handle implementation details like extracting the values from a JSON String where possible. The Items shouldn’t care what format the data came in to begin with.

@Bassdriver describes the easiest way to handle this by creating the separate Channels.

Hi Rich,

I got it working with the 2-step transformation approach on a single Channel into multiple different items. On the Channel I do the JSONPATH transformation to extract all price elements into a string. That string I process with a transformation profile using custom JavaScript into multiple different Number Items. :nerd_face:

// Transforms a string to a single element
(function(i,j) {
    var item = parseInt(j);   // array index as int
    var fixed = i.slice(1,i.length-1);   // remove brackets from incoming string
    var list = fixed.split(",");    // turn string into an array
    var price = parseFloat(list[item]);   // select the requested item as float
    return price;   // return the float number
})(input, item)