Extract data from object based on its place in the object

Hello,

How can I use a value from a object, based on its place in the object? I use a API that returns a result:
payload

the problem is that the date is part of the object and will change every day.

I'm only interested in thevalue 2nd date "2023-01-22" in this flow

[
    {
        "id": "67ae90406b6c9f81",
        "type": "inject",
        "z": "b29659afe04a7d40",
        "name": "",
        "props": [
            {
                "p": "payload"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "{\"result\":{\"2023-01-21\":18734,\"2023-01-22\":15786},\"message\":{\"code\":0,\"type\":\"success\",\"text\":\"\",\"info\":{\"latitude\":50.8154,\"longitude\":3.3773,\"distance\":0,\"place\":\"62, Otegemse steenweg, Deerlijk, Kortrijk, West-Vlaanderen, Vlaanderen, 8540, België / Belgique / Belgien\",\"timezone\":\"Europe/Brussels\",\"time\":\"2023-01-21T15:51:13+01:00\",\"time_utc\":\"2023-01-21T14:51:13+00:00\"},\"ratelimit\":{\"period\":3600,\"limit\":12,\"remaining\":11}}}",
        "payloadType": "jsonata",
        "x": 350,
        "y": 200,
        "wires": [
            [
                "4c35102c3b553ede"
            ]
        ]
    }
]

Is ther a way to isolate thet value of the 2nd date in the object?
I checked already a lot of research but with no succes

Kind regards Tim

No doubt it's possible with fewer nodes, JSONata, but this should work.

[{"id":"a5b6d2f4c0c645fe","type":"function","z":"7726835ff669c023","name":"Sample data","func":"msg.payload = { result: \n    {\"2023-01-21\": 18734,\n    \"2023-01-22\": 15786}\n}\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":310,"y":100,"wires":[["2c0d74997b2c801c"]]},{"id":"4ee96b3158372633","type":"inject","z":"7726835ff669c023","name":"go","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":170,"y":100,"wires":[["a5b6d2f4c0c645fe"]]},{"id":"a54f2807009aca9b","type":"split","z":"7726835ff669c023","name":"split on ,","splt":",","spltType":"str","arraySplt":1,"arraySpltType":"len","stream":false,"addname":"","x":620,"y":100,"wires":[["5ef2772f4b4b557c"]]},{"id":"2c0d74997b2c801c","type":"change","z":"7726835ff669c023","name":"Just .result","rules":[{"t":"move","p":"payload.result","pt":"msg","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":470,"y":100,"wires":[["a54f2807009aca9b"]]},{"id":"5ef2772f4b4b557c","type":"switch","z":"7726835ff669c023","name":"index 1","property":"parts.index","propertyType":"msg","rules":[{"t":"eq","v":"1","vt":"num"}],"checkall":"true","repair":false,"outputs":1,"x":760,"y":100,"wires":[["0fba146143bb4af8","7bf23c501aed9df2"]]},{"id":"0fba146143bb4af8","type":"debug","z":"7726835ff669c023","name":"payload","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":900,"y":100,"wires":[]},{"id":"7bf23c501aed9df2","type":"debug","z":"7726835ff669c023","name":"parts.key","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"parts.key","targetType":"msg","statusVal":"","statusType":"auto","x":900,"y":140,"wires":[]}]

The JSONata expression would be
$keys($$.payload.result)[1]
example

[{"id":"67ae90406b6c9f81","type":"inject","z":"da8a6ef0b3c9a5c8","name":"","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"{\"result\":{\"2023-01-21\":18734,\"2023-01-22\":15786},\"message\":{\"code\":0,\"type\":\"success\",\"text\":\"\",\"info\":{\"latitude\":50.8154,\"longitude\":3.3773,\"distance\":0,\"place\":\"62, Otegemse steenweg, Deerlijk, Kortrijk, West-Vlaanderen, Vlaanderen, 8540, België / Belgique / Belgien\",\"timezone\":\"Europe/Brussels\",\"time\":\"2023-01-21T15:51:13+01:00\",\"time_utc\":\"2023-01-21T14:51:13+00:00\"},\"ratelimit\":{\"period\":3600,\"limit\":12,\"remaining\":11}}}","payloadType":"json","x":230,"y":4200,"wires":[["f7c765e3a489d940"]]},{"id":"f7c765e3a489d940","type":"change","z":"da8a6ef0b3c9a5c8","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"$keys($$.payload.result)[1]","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":400,"y":4200,"wires":[["0fba146143bb4af8"]]},{"id":"0fba146143bb4af8","type":"debug","z":"da8a6ef0b3c9a5c8","name":"payload","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":580,"y":4200,"wires":[]}]

Or Javascript in a function node

msg.payload = Object.keys(msg.payload.result)[1]

@E1cid @jbudd Are you sure you can rely on the order of the keys? Doesn't it depend on how the object was constructed? I think it may be necessary to sort the keys first. A simple alpha type search will be ok.

@TimC1986 do you have any control over the data? Where is it coming from? It would be better if the data were in a sorted array, something like

[
  {date: "2023-01-21", value: 18734},
  {date: "2023-01-22", value: 15786}
]

Then you simply use msg.payload[1].date.

1 Like

Colin you know very well that you can not be certain dictionaries(objects) order, and you know both @jbudd and myself know it to.

If the order of the return object can not be trusted, i.e the device sending alters it, which i doubt happens in this case, you can use

(
   $keys($$.payload.result).{
       "date": $,
       "value": $lookup($$.payload.result, $)
   }
)^(date)[1].date

Yes, probably wise to sort on msg.parts.key. One more node :yawning_face:

I wonder which of the 3 methods would be fastest if the payload object was of considerable size.
The javascript function wins on screen real estate and readability.

1 Like

Well actually I wasn't certain what the current position is. I remember seeing recently that there was a change to the language that did enforce an order in some way, but I wasn't sure what it was.

Hi thanks for the helping hand, works perfect!

Hi Colin, no I don't have control over the data, it comes from a API from a solar forecast service.

Thanks for the help I will check this out

Thanks E1cid, I tried the flow but works not directly, but I will look on it in detail and can definitly learn something with it. Thanks

I think you wanted the value not the date so replace .date with .value

No I meant to use .date, as that what I believe the OP specified. two other contributors to this thread seem to think the same, we may have misunderstood the OP's post though.

Yes, but that was the only reason that I could see why he said that your ingenious code wouldn't work. It took me ages pouring through the JSONata how-to to work out what you had done. :grinning:

1 Like

Your comment makes more sense to me know. Cheers

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