# A Change node JSONata question

**URL:** <https://discourse.nodered.org/t/a-change-node-jsonata-question/77023>\
**Category:** General\
**Created:** [28 March 2023 15:41 UTC](https://discourse.nodered.org/t/a-change-node-jsonata-question/77023 "2023-03-28T15:41:31Z")\
**Posts on this page:** 12\
**Page:** 1

<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:** [28 March 2023 15:41 UTC](https://discourse.nodered.org/t/a-change-node-jsonata-question/77023/1 "2023-03-28T15:41:31Z")

</div>

I have two global variables:  
**global.mac** = "E4:5F:01:FE:DC:BA"  
and  
**global.macvendors** = {  
"E8:48:B8":"TP-Link",  
"E4:5F:01":"Raspberry Pi",  
"5C:CF:7F":"Espressif",  
"D8:49:2F":"Canon"  
}

So the vendor bit of **mac** is **$substring($globalContext("mac"), 0, 8)** or "E4:5F:01"  
And the vendor is **$globalContext("macvendors")."E4:5F:01"** or "Raspberry Pi"

But I can't work out how to combine the two into a single command to get "Raspberry Pi"  
**$globalContext("macvendors").$substring($globalContext("mac"), 0, 8)** is valid JSONata but confusingly it returns the mac address substring "E4:5F:01"

1. How should I do this?
2. Is **macvendors** structured properly or should it be an array?

---

<div class="post-metadata">

**Author:** ![marcus-j-davies](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/marcus-j-davies/32/103435_2.png) [@marcus-j-davies](https://discourse.nodered.org/u/marcus-j-davies)\
**Post date:** [28 March 2023 15:58 UTC](https://discourse.nodered.org/t/a-change-node-jsonata-question/77023/2 "2023-03-28T15:58:55Z")

</div>

Hi @jbudd

I believe this will work

- Look up a value based on its key

I don't do much JSONata - so forgive me, if incorrect

```auto
$lookup($globalContext("macvendors"), $substring($globalContext("mac"), 0, 8))

```

---

<div class="post-metadata">

**Author:** ![TotallyInformation](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/totallyinformation/32/31_2.png) [@TotallyInformation](https://discourse.nodered.org/u/TotallyInformation)\
**Post date:** [28 March 2023 15:59 UTC](https://discourse.nodered.org/t/a-change-node-jsonata-question/77023/3 "2023-03-28T15:59:30Z")

</div>

Try this:

```auto
(
    $x := $substring($globalContext("mac"), 0, 8);

    $globalContext("macvendors").$x
)

```

---

<div class="post-metadata">

**Author:** ![TotallyInformation](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/totallyinformation/32/31_2.png) [@TotallyInformation](https://discourse.nodered.org/u/TotallyInformation)\
**Post date:** [28 March 2023 16:02 UTC](https://discourse.nodered.org/t/a-change-node-jsonata-question/77023/4 "2023-03-28T16:02:30Z")

</div>

> [@marcus-j-davies](#):
>
> `$lookup($globalContext("macvendors"), $substring($globalContext("mac"), 0, 8))`

Oops, mine returns the vendor mac not the name! Yours is, of course, much better. 🙂

---

<div class="post-metadata">

**Author:** ![marcus-j-davies](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/marcus-j-davies/32/103435_2.png) [@marcus-j-davies](https://discourse.nodered.org/u/marcus-j-davies)\
**Post date:** [28 March 2023 16:09 UTC](https://discourse.nodered.org/t/a-change-node-jsonata-question/77023/5 "2023-03-28T16:09:01Z")

</div>

I use JSONata in my contributed node - I need to question my self if it doesn't work 😁

I say 'use' - I allow it to be 😅

---

<div class="post-metadata">

**Author:** ![TotallyInformation](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/totallyinformation/32/31_2.png) [@TotallyInformation](https://discourse.nodered.org/u/TotallyInformation)\
**Post date:** [28 March 2023 16:12 UTC](https://discourse.nodered.org/t/a-change-node-jsonata-question/77023/6 "2023-03-28T16:12:57Z")

</div>

Yes, many of mine now allow its use as well - though it is a pain to accommodate since it is async. I must admit that I've started using it a bit more since then as it is a great way to quickly add some dynamic processing to a field. Annoying though when you realise that you imagined seeing `$sin` and `$tan` functions in the list! 🤣

---

<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:** [28 March 2023 16:19 UTC](https://discourse.nodered.org/t/a-change-node-jsonata-question/77023/7 "2023-03-28T16:19:13Z")

</div>

Thanks both.

Yup, Marcus' $lookup works.  
But why can I use  
$globalContext("macvendors").string but not  
$globalContext("macvendors").$function?

I think Julian's is a multi-line equivalent of my attempt.  
I had attempted := (Pascal!) and ; but they were rejected.  
Seems like the brackets round the whole lot are important.

I'm really not warming to JSONata's syntax 🤯

---

<div class="post-metadata">

**Author:** ![marcus-j-davies](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/marcus-j-davies/32/103435_2.png) [@marcus-j-davies](https://discourse.nodered.org/u/marcus-j-davies)\
**Post date:** [28 March 2023 16:25 UTC](https://discourse.nodered.org/t/a-change-node-jsonata-question/77023/8 "2023-03-28T16:25:17Z")

</div>

I would agree - its a little odd.  
its a love/hate relationship - I do like to use it in the right situation, but its a little odd in behaviour at times

---

<div class="post-metadata">

**Author:** ![TotallyInformation](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/totallyinformation/32/31_2.png) [@TotallyInformation](https://discourse.nodered.org/u/TotallyInformation)\
**Post date:** [28 March 2023 18:15 UTC](https://discourse.nodered.org/t/a-change-node-jsonata-question/77023/9 "2023-03-28T18:15:46Z")

</div>

> [@jbudd](#):
>
> But why can I use

I suspect it is due to the overloaded use of the dot separator. It is happy with a variable but not a function. I've been at this game far too long! 😂

Yes the round brackets are critical.

---

<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:** [28 March 2023 18:48 UTC](https://discourse.nodered.org/t/a-change-node-jsonata-question/77023/10 "2023-03-28T18:48:33Z")

</div>

> [@TotallyInformation](#):
>
> I suspect it is due to the overloaded use of the dot separator. It is happy with a variable but not a function.

It doesn't like variables either, that's why your expression returned the substring of the mac. The issue is the dot has two meanings, one the path notation, and two the mapping function. I think that is why they have lookup() rather than `[]`.

Anyway here is an alternative way just for info.

```auto
$globalContext("macvendors." & $substring($globalContext("mac"), 0, 8))

```

Alternatively if the mac was in a msg property you could do it in the change node with no JSONata  
set `msg.` `payload`  
to `global``macvendors[msg.mac]`

---

<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:** [28 March 2023 21:36 UTC](https://discourse.nodered.org/t/a-change-node-jsonata-question/77023/11 "2023-03-28T21:36:18Z")

</div>

@E1cid's versions work too.

> [@E1cid](#):
>
> an alternative why just for info.
> 
> `$globalContext("macvendors." & $substring($globalContext("mac"), 0, 8))`

OK "macvenddors." & $substring($globalContext("mac"), 0, 8) is concatenation so this is  
`$globalContext("macvendors.E4:5F:01")`  
And indeed similar (javascript) syntax in a function node:  
`msg.payload = global.get("macvendors.E4:5F:01")` works (who knew?)

> [@E1cid](#):
>
> Alternatively if the mac was in a msg property you could do it in the change node with no JSONata  
> set `msg.` `payload`  
> to `global` `macvendors[msg.mac]`

"with no JSONata" wow, surprised to see that 😆

Thanks for the suggestions everyone, lots of food for thought there.

Three different solutions gathered together:

 ![Untitled 1](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/b/5/b5a1152489a76bb570838ebd142748e766704fa2.jpeg)

```auto
[{"id":"4519255c81d7c9d5","type":"inject","z":"52d3a9a7a5712824","name":"init","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":true,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":190,"y":1600,"wires":[["ec0e3ae6bef510f7"]]},{"id":"ec0e3ae6bef510f7","type":"change","z":"52d3a9a7a5712824","name":"set variables","rules":[{"t":"set","p":"mac","pt":"flow","to":"E4:5F:01:FE:DC:BA","tot":"str"},{"t":"set","p":"macvendors","pt":"flow","to":"{ \"E8:48:B8\":\"TP-Link\", \"E4:5F:01\":\"Raspberry Pi\", \"5C:CF:7F\":\"Espressif\", \"D8:49:2F\":\"Canon\" }","tot":"json"}],"action":"","property":"","from":"","to":"","reg":false,"x":390,"y":1600,"wires":[[]]},{"id":"a7eb29e38e1d826d","type":"group","z":"52d3a9a7a5712824","name":"@marcus-j-davies $lookup($flowContext(\"macvendors\"), $substring($flowContext(\"mac\"), 0, 8))","style":{"label":true},"nodes":["982b91a425b9e71b","31381589b1707f68","0a83a3ca160b355c"],"x":114,"y":1639,"w":612,"h":82},{"id":"982b91a425b9e71b","type":"change","z":"52d3a9a7a5712824","g":"a7eb29e38e1d826d","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"$lookup($flowContext(\"macvendors\"), $substring($flowContext(\"mac\"), 0, 8))","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":400,"y":1680,"wires":[["0a83a3ca160b355c"]]},{"id":"31381589b1707f68","type":"inject","z":"52d3a9a7a5712824","g":"a7eb29e38e1d826d","name":"go","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"go","payloadType":"str","x":210,"y":1680,"wires":[["982b91a425b9e71b"]]},{"id":"0a83a3ca160b355c","type":"debug","z":"52d3a9a7a5712824","g":"a7eb29e38e1d826d","name":"debug 309","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":610,"y":1680,"wires":[]},{"id":"6e1dcc21fee97c56","type":"group","z":"52d3a9a7a5712824","name":"@ElCid #1: $flowContext(\"macvendors.\" & $substring($flowContext(\"mac\"), 0, 8))","style":{"label":true},"nodes":["773e66171b33cfc2","1de3b5add251d57b","d86fbc2e20c888af"],"x":114,"y":1739,"w":612,"h":82},{"id":"773e66171b33cfc2","type":"debug","z":"52d3a9a7a5712824","g":"6e1dcc21fee97c56","name":"debug 308","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":610,"y":1780,"wires":[]},{"id":"1de3b5add251d57b","type":"change","z":"52d3a9a7a5712824","g":"6e1dcc21fee97c56","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"$flowContext(\"macvendors.\" & $substring($flowContext(\"mac\"), 0, 8))","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":400,"y":1780,"wires":[["773e66171b33cfc2"]]},{"id":"d86fbc2e20c888af","type":"inject","z":"52d3a9a7a5712824","g":"6e1dcc21fee97c56","name":"go","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"go","payloadType":"str","x":210,"y":1780,"wires":[["1de3b5add251d57b"]]},{"id":"b89f37ba67995e4c","type":"group","z":"52d3a9a7a5712824","name":"@ElCid #2 flow.macvendors[msg.myvendor]","style":{"label":true},"nodes":["7e01a416dcc22a61","8b448abe55d9b4cd","831fd2640cacf854"],"x":114,"y":1839,"w":612,"h":82},{"id":"7e01a416dcc22a61","type":"change","z":"52d3a9a7a5712824","g":"b89f37ba67995e4c","name":"","rules":[{"t":"set","p":"myvendor","pt":"msg","to":"$substring($flowContext(\"mac\"), 0, 8)","tot":"jsonata"},{"t":"set","p":"payload","pt":"msg","to":"macvendors[msg.myvendor]","tot":"global"}],"action":"","property":"","from":"","to":"","reg":false,"x":400,"y":1880,"wires":[["8b448abe55d9b4cd"]]},{"id":"8b448abe55d9b4cd","type":"debug","z":"52d3a9a7a5712824","g":"b89f37ba67995e4c","name":"debug 307","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":610,"y":1880,"wires":[]},{"id":"831fd2640cacf854","type":"inject","z":"52d3a9a7a5712824","g":"b89f37ba67995e4c","name":"go","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"go","payloadType":"str","x":210,"y":1880,"wires":[["7e01a416dcc22a61"]]}]

```

---

<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:** [27 May 2023 21:36 UTC](https://discourse.nodered.org/t/a-change-node-jsonata-question/77023/12 "2023-05-27T21:36:50Z")

</div>

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