Need a jsonata magician!

Guys,

I am extracting weather data from our BOM in Sydney and then want to use the Min and Max Temperatures (which are presented as an object) to make decisions in relation to home heating etc

Currently - this is what the returned data looks like - which i am storing in Context Data using a change node

Here is an excerpt of the flow that stores them all - the main point is that it is a change node that is grabbing a message object that is passed in and then ripping it apart to store the information for later use

image

What i would like to do is to store the Min and Max temperatures as pure numbers - rather than with the C and degrees sign

I put together a change node that took 3 steps (3 seperate changes within the one node using Jsonata - but am unable to collaps that down to a single step) and have it operate across all the values

Anybody put me on the right track for how to incorporate this into the main change object ?

Craig

Hello .. you could use in the Change node, that you set the globals, a single line of Jsonata

For Example :

maybe i misunderstood the part of the question

Since you are selecting specific elements in the array and renaming them to Today, Tomorrow, 2DaysTime etc
i dont know if there is an easier way than what you have done already .. except optimizing the jsonata

If these are only integer values - use $parseInteger to extract the numeric part

and for sure you can directly assign it to your global value and use the path of the payload object as specified by @UnborN

so you can

$parseInteger(payload[2].air_temperature_minimum,'0') in your JSONATA field of the change node.

If the temperature values are not only integers - then you can also use the $replace function in combination with a regular expression. But as I could see - your temperature values are only integers.

Thanks Unborn - i will give that another try - i was building that up in a seperate test node and got it down to 2 steps but could not get it to work as a single step as you have documented.

Will try again (now i know it should work) and report back

Craig

Thanks Micky - they are only integers - so will try the first one and see how we go and report back

Craig

Take care that you use

$parseInteger(payload[2].air_temperature_minimum,'0')

only payload and not msg.payload in your JSONATA expressions.

Can i ask why that is ? I currently have tried it with msg.payload and it appears to be working and doing what i want

Just trying to understand (and thanks for taking them time to post this up)

Craig

I read somewhere that msg.property will no longer supported in the future.
If you have no complicated calculations you can directly address the properties of the msg object.
In case you are down somewhere in your JSONATA calculations then you should refer to the parent object always with $$.

So $$.payload would also refer to the payload property of the msg object.

Instead of trying to manipulate each field inside a separate change node rule, I would tend to process the entire array of 7 days into a single global.Weather object --

because it looks like each day can use the same expression to do the restructuring:

(
    $daysTime := function($idx) {(
        $idx = 0 ? "Today" :
            $idx = 1 ? "Tomorrow" :
            $idx & "DaysTime"
    )};

    payload#$i {
        $daysTime($i): {
            "Description": precis,
            "Temperature": {
                "Minimum": $parseInteger(air_temperature_min, '0'),
                "Maximum": $parseInteger(air_temperature_max, '0')
            }
        }
    }
)

Only the field name "XDaysTime" requires a function, based on the index in the original weather data array (0 is Today, 1 is Tomorrow, etc).

Love jsonata or hate it, to me that looks pretty readable -- and the output structure is shown right in the nesting of the expression itself. BTW, next time please include the actual data as some JSON we can copy, rather than as a screen capture...

1 Like

Wow - OK that does what you needs doing - but i will need to study it some more to make sure i understand it before i deploy something like that.

Is there a way to comment the code in JSONATA so when i come back to it in two years (as i am sure the Australian BOM will change the data format !) then i will understand what each step is doing ?

Will do re posting code in future - i just thought in this case as you did not have access to the data it would have been of little value.

Craig

Aah thanks for that - makes perfect sense so things do not break in the future.

Craig

Why yes there is:

(
    /* field name as a function of array index */
    $daysTime := function($idx) {(
        $idx = 0 ? "Today" :
        $idx = 1 ? "Tomorrow" :
        $idx & "DaysTime"
    )};

    payload#$i { /* iterate over payload array, save index in $i */
        $daysTime($i): { /* use the array index to derive the field name */
            "Description": precis,
            "Temperature": { /* convert temps to integers, ignore units */
                "Minimum": $parseInteger(air_temperature_min, '0'),
                "Maximum": $parseInteger(air_temperature_max, '0')
            }
        }
    }
)

Guess I should have done that in the first place...

1 Like

You can comment in the node itself or within the JSONATA code,
see: Programming constructs · JSONata

JSONata expressions can be interleaved with comments using 'C' style comment delimeters. For example,

so you can use

/* a comment */
1 Like

Right, the flows calling the BOM service would not be useful -- but if you copy the json output structure directly from the debug sidebar and include it in a code block, it's so much easier!

Thanks for Persisting with me on this one - i will use the Jsonata you have supplied and comment it up (will make sure your name is all over it - so i know who to come back to in the future !!)

Craig

2 Likes

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.