# JSONata: Using the result of an Object Function to reference a Message Property in a Change Node

**URL:** <https://discourse.nodered.org/t/jsonata-using-the-result-of-an-object-function-to-reference-a-message-property-in-a-change-node/73505>\
**Category:** General\
**Created:** [11 January 2023 01:10 UTC](https://discourse.nodered.org/t/jsonata-using-the-result-of-an-object-function-to-reference-a-message-property-in-a-change-node/73505 "2023-01-11T01:10:59Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![simon.ingham](https://avatars.discourse-cdn.com/v4/letter/s/aca169/32.png) [@simon.ingham](https://discourse.nodered.org/u/simon.ingham)\
**Post date:** [11 January 2023 01:10 UTC](https://discourse.nodered.org/t/jsonata-using-the-result-of-an-object-function-to-reference-a-message-property-in-a-change-node/73505/1 "2023-01-11T01:10:59Z")

</div>

Hello all,

I'm new to Node-RED and have been struggling with using JSONata to set nested object properties with the Change Node.

I have the following scenario where I need to access a particular property's value in a nested object, but where I don't know the name one of the parent properties.

I can get the property name using `$keys(object)` however I then need to use the output of this as part of the dot notation to access the required property. A possible added complication is a hyphen in the unknown property name.

Despite some extensive research I just can't work out the correct syntax to achieve this.

Example object (where the property name "device-0001" is unknown in advance):

```auto
{
    "device-0001": {
        "name1": "value 1",
        "name2": "value 2"
    }
}

```

I can get the unknown property name with `$keys(object)`

```auto
$keys($.payload)[0]

```

which returns `"device-0001"`

However, if I use this as part of the dot notation

```auto
$.payload.$keys($.payload)[0].name1

```

then I get `undefined` returned.

Although I do have two work arounds

1. Save the object to the flow context first

```auto
$flowContext("devices." & $keys($flowContext("devices"))[0] & ".name1")

```

1. Use a function node and JS

```auto
msg.payload = msg.payload[Object.keys(msg.payload)[0]].name1;
return msg;

```

I don't want to have to change several existing change nodes to functions nodes if possible and would prefer not to use the flow context. I also feel it should just be matter of using the correct syntax.

Any advice would be appreciated.

Regards

Simon

(Node-RED: v3.0.2)  
(Node.js: v18.2.1)

---

<div class="post-metadata">

**Author:** ![bakman2](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/bakman2/32/6207_2.png) [@bakman2](https://discourse.nodered.org/u/bakman2)\
**Post date:** [11 January 2023 05:20 UTC](https://discourse.nodered.org/t/jsonata-using-the-result-of-an-object-function-to-reference-a-message-property-in-a-change-node/73505/2 "2023-01-11T05:20:45Z")

</div>

Welcome.

Is the input a single object or an array of objects ? Are you interested in the 'unknown device' ? or do you only want the `name1` property ?

In jsonata you can use `payload.*.name1`

It will easier to get help if you can provide the input payload and the expected output.

---

<div class="post-metadata">

**Author:** ![jbudd](https://avatars.discourse-cdn.com/v4/letter/j/5f8ce5/32.png) [@jbudd](https://discourse.nodered.org/u/jbudd)\
**Post date:** [11 January 2023 05:42 UTC](https://discourse.nodered.org/t/jsonata-using-the-result-of-an-object-function-to-reference-a-message-property-in-a-change-node/73505/3 "2023-01-11T05:42:15Z")

</div>

Does this work?

```auto
[
    {
        "id": "b1e189a05183e321",
        "type": "change",
        "z": "7aef6aee2ebec20b",
        "name": "",
        "rules": [
            {
                "t": "set",
                "p": "key",
                "pt": "msg",
                "to": "$keys($.payload)[0]",
                "tot": "jsonata"
            },
            {
                "t": "set",
                "p": "payload",
                "pt": "msg",
                "to": "payload[msg.key].name1",
                "tot": "msg"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 520,
        "y": 120,
        "wires": [
            [
                "5fa6a2c8cdd5e7c7"
            ]
        ]
    }
]

```

---

<div class="post-metadata">

**Author:** ![E1cid](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/e1cid/32/77971_2.png) [@E1cid](https://discourse.nodered.org/u/E1cid)\
**Post date:** [11 January 2023 07:57 UTC](https://discourse.nodered.org/t/jsonata-using-the-result-of-an-object-function-to-reference-a-message-property-in-a-change-node/73505/4 "2023-01-11T07:57:40Z")

</div>

Both @jbudd and @bakman2 answers will work. It really depends if the object is as you have shown.  
Another alternative is to use the $lookup function.  
e.g

```auto
$lookup($$.payload, $keys($$.payload)[0]).name1

```

---

<div class="post-metadata">

**Author:** ![simon.ingham](https://avatars.discourse-cdn.com/v4/letter/s/aca169/32.png) [@simon.ingham](https://discourse.nodered.org/u/simon.ingham)\
**Post date:** [11 January 2023 10:08 UTC](https://discourse.nodered.org/t/jsonata-using-the-result-of-an-object-function-to-reference-a-message-property-in-a-change-node/73505/7 "2023-01-11T10:08:34Z")

</div>

Hi,

Thank you @bakman2, it is just a single object in this case although I can imagine scenarios where it may be an array of objects in the future. In this instance I'm also not interested in the device property name so `payload.*.name1` will work great. I must have missed that you could use wildcards in JSONata, so useful to know about that, thank you

Thank you @jbudd, using two rules works great, slightly disappointed with myself for not thinking of that one!

Thank you @E1cid using `$lookup($$.payload, $keys($$.payload)[0]).name1` works great. It is also good to learn about another function, so thank you.

I only didn't include the actual object and required output as it is such a large object with a lot of properties and would have made the original post long.

Thank you all for your assistance, really appreciated.

Simon

---

<div class="post-metadata">

**Author:** ![bakman2](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/bakman2/32/6207_2.png) [@bakman2](https://discourse.nodered.org/u/bakman2)\
**Post date:** [11 January 2023 10:16 UTC](https://discourse.nodered.org/t/jsonata-using-the-result-of-an-object-function-to-reference-a-message-property-in-a-change-node/73505/8 "2023-01-11T10:16:49Z")

</div>

> I must have missed that you could use wildcards in JSONata

It is one of the core features to use it.

You could make it even easier by just using `**.name1`, it will traverse through the all its descendants (but could potentially create problems if the same property name is used on multiple levels)

jsonata is extremely powerful, but can be extremely confusing at the same time :')

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/1X/d073cd938eafa2e558d7c2cd59003b3ef4963033.png) [@system](https://discourse.nodered.org/u/system)\
**Post date:** [25 January 2023 10:17 UTC](https://discourse.nodered.org/t/jsonata-using-the-result-of-an-object-function-to-reference-a-message-property-in-a-change-node/73505/9 "2023-01-25T10:17:07Z")

</div>

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