# What is the correct way to use jsonata inside a switch node with "has key" rule?

**URL:** <https://discourse.nodered.org/t/what-is-the-correct-way-to-use-jsonata-inside-a-switch-node-with-has-key-rule/83616>\
**Category:** General\
**Tags:** switch-node, jsonata\
**Created:** [11 December 2023 18:49 UTC](https://discourse.nodered.org/t/what-is-the-correct-way-to-use-jsonata-inside-a-switch-node-with-has-key-rule/83616 "2023-12-11T18:49:52Z")\
**Posts on this page:** 14\
**Page:** 1

<div class="post-metadata">

**Author:** ![alwinter](https://avatars.discourse-cdn.com/v4/letter/a/df788c/32.png) [@alwinter](https://discourse.nodered.org/u/alwinter)\
**Post date:** [11 December 2023 18:49 UTC](https://discourse.nodered.org/t/what-is-the-correct-way-to-use-jsonata-inside-a-switch-node-with-has-key-rule/83616/1 "2023-12-11T18:49:52Z")

</div>

Hi

I have the following situation, I want to test if a given msg.payload has some keys. Let's say for example:

```auto
msg.payload.keyOne
msg.payload.keyTwo

```

I know i can check that with a function node, but I'm curious about achieving that with jsonata. Using the following expression:

```auto

has key: "keyOne"

```

actually works. But:

`has key: "keyOne" and "keyTwo"`

does not.

nor $.(keyOne and keyTwo) as jsonata expression

I tried several approaches but I'm not sure how can i achieve that. Apart from creating a function node and creating the logic inside it.

---

<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 December 2023 20:02 UTC](https://discourse.nodered.org/t/what-is-the-correct-way-to-use-jsonata-inside-a-switch-node-with-has-key-rule/83616/2 "2023-12-11T20:02:16Z")

</div>

This seems to work:

 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/5/1/519f2cf35848db7c188491f56a2d6d0cb626155a.png)

---

<div class="post-metadata">

**Author:** ![alwinter](https://avatars.discourse-cdn.com/v4/letter/a/df788c/32.png) [@alwinter](https://discourse.nodered.org/u/alwinter)\
**Post date:** [11 December 2023 20:14 UTC](https://discourse.nodered.org/t/what-is-the-correct-way-to-use-jsonata-inside-a-switch-node-with-has-key-rule/83616/4 "2023-12-11T20:14:28Z")

</div>

thank you very much, I tried several ways but it seems I didn't try that one. Since i was already selecting msg.payload in the property i though that was not necessary in the expression.

---

<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 December 2023 20:18 UTC](https://discourse.nodered.org/t/what-is-the-correct-way-to-use-jsonata-inside-a-switch-node-with-has-key-rule/83616/5 "2023-12-11T20:18:30Z")

</div>

I was astonished my attempt worked too! Definitely can't explain it, I don't speak Jsonata.

Note that it does not work with  
`payload: {"keyOne": false, "keyTwo:" 42}`

---

<div class="post-metadata">

**Author:** ![Colin](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/colin/32/17040_2.png) [@Colin](https://discourse.nodered.org/u/Colin)\
**Post date:** [11 December 2023 20:53 UTC](https://discourse.nodered.org/t/what-is-the-correct-way-to-use-jsonata-inside-a-switch-node-with-has-key-rule/83616/6 "2023-12-11T20:53:04Z")

</div>

The reason is that the test is not testing the presence but whether they are truthy. So each one is cast to be a boolean and then the AND performed

---

<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 December 2023 21:19 UTC](https://discourse.nodered.org/t/what-is-the-correct-way-to-use-jsonata-inside-a-switch-node-with-has-key-rule/83616/7 "2023-12-11T21:19:44Z")

</div>

I would think, if payload has only the two keys

```auto
["keyOne","keyTwo"] = [$keys($$.payload)]

```

in property input and is true as rule

e.g.

```auto
[{"id":"2cabca371eb27b4e","type":"inject","z":"d1395164b4eec73e","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"{\"keyOne\":false,\"keyTwo\":42}","payloadType":"json","x":90,"y":2200,"wires":[["2461013912501444"]]},{"id":"2461013912501444","type":"switch","z":"d1395164b4eec73e","name":"","property":"[\"keyOne\",\"keyTwo\"] = [$keys($$.payload)]","propertyType":"jsonata","rules":[{"t":"true"}],"checkall":"true","repair":false,"outputs":1,"x":230,"y":2200,"wires":[["51e23011bba3999b"]]},{"id":"fdf90a4bf8ad5b04","type":"inject","z":"d1395164b4eec73e","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"{\"keyOne\":false,\"keyThree\":42}","payloadType":"json","x":90,"y":2240,"wires":[["2461013912501444"]]},{"id":"51e23011bba3999b","type":"debug","z":"d1395164b4eec73e","name":"debug 2460","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":410,"y":2200,"wires":[]}]

```

Or if multiple properties of payload

```auto
$count($keys($$.payload)[$ in ["keyOne","keyTwo"]])

```

and rule == 2  
e.g.

```auto
[{"id":"2cabca371eb27b4e","type":"inject","z":"d1395164b4eec73e","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"{\"keyOne\":false,\"keyTwo\":42, \"test\":33}","payloadType":"json","x":90,"y":2200,"wires":[["a6629ce22e09cfe9"]]},{"id":"a6629ce22e09cfe9","type":"switch","z":"d1395164b4eec73e","name":"","property":"$count($keys($$.payload)[$ in [\"keyOne\",\"keyTwo\"]])","propertyType":"jsonata","rules":[{"t":"eq","v":"2","vt":"num"}],"checkall":"true","repair":false,"outputs":1,"x":250,"y":2200,"wires":[["51e23011bba3999b"]]},{"id":"5133659df03aee6e","type":"inject","z":"d1395164b4eec73e","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"{\"keyOne\":false,\"keyThree\":42}","payloadType":"json","x":90,"y":2240,"wires":[["a6629ce22e09cfe9"]]},{"id":"51e23011bba3999b","type":"debug","z":"d1395164b4eec73e","name":"debug 2460","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":410,"y":2200,"wires":[]}]

```

---

<div class="post-metadata">

**Author:** ![alwinter](https://avatars.discourse-cdn.com/v4/letter/a/df788c/32.png) [@alwinter](https://discourse.nodered.org/u/alwinter)\
**Post date:** [11 December 2023 21:32 UTC](https://discourse.nodered.org/t/what-is-the-correct-way-to-use-jsonata-inside-a-switch-node-with-has-key-rule/83616/8 "2023-12-11T21:32:08Z")

</div>

> [@E1cid](#):
>
> `[{"id":"2cabca371eb27b4e","type":"inject","z":"d1395164b4eec73e","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"{\"keyOne\":false,\"keyTwo\":42}","payloadType":"json","x":90,"y":2200,"wires":[["2461013912501444"]]},{"id":"2461013912501444","type":"switch","z":"d1395164b4eec73e","name":"","property":"[\"keyOne\",\"keyTwo\"] = [$keys($.payload)]","propertyType":"jsonata","rules":[{"t":"true"}],"checkall":"true","repair":false,"outputs":1,"x":230,"y":2200,"wires":[["51e23011bba3999b"]]},{"id":"fdf90a4bf8ad5b04","type":"inject","z":"d1395164b4eec73e","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"{\"keyOne\":false,\"keyThree\":42}","payloadType":"json","x":90,"y":2240,"wires":[["2461013912501444"]]},{"id":"51e23011bba3999b","type":"debug","z":"d1395164b4eec73e","name":"debug 2460","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":410,"y":2200,"wires":[]}]`

But in the property negates the possibility of using other rules in the switch statement (my case). But actually your solution works well as a rule anyway as jsonata expression. So thanks for your help.

One of the reasons for looking into jsonata is that i tend to use switch cases and usually i send an int code to a switch statement trough a fuction node, but having jsonata can reduce the amounts of nodes in certain scenarios.

---

<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 December 2023 21:35 UTC](https://discourse.nodered.org/t/what-is-the-correct-way-to-use-jsonata-inside-a-switch-node-with-has-key-rule/83616/9 "2023-12-11T21:35:10Z")

</div>

> [@alwinter](#):
>
> But in the property negates the possibility of using other rules

You never said you wanted to use other rules.  
But just move the whole thing to a rule  
e.g.

```auto
$count(["keyOne","keyTwo"][$ in $keys($$.payload)]) = 2

```

Or

```auto
["keyOne","keyTwo"] = [$keys($$.payload)] 

```

[edit] reversed the expression as would use less processing if payload had more properties.

---

<div class="post-metadata">

**Author:** ![alwinter](https://avatars.discourse-cdn.com/v4/letter/a/df788c/32.png) [@alwinter](https://discourse.nodered.org/u/alwinter)\
**Post date:** [11 December 2023 21:50 UTC](https://discourse.nodered.org/t/what-is-the-correct-way-to-use-jsonata-inside-a-switch-node-with-has-key-rule/83616/10 "2023-12-11T21:50:13Z")

</div>

> [@E1cid](#):
>
> You never said you wanted to use other rules.  
> But just move the whole thing to a rule  
> e.g.

Yes that's true I didn't mention it. I was just pointing that out trying to find the most versatile solution, not necessarily for my specific case, so sorry for any misunderstanding. Yes i mentioned in my comment as well that could work as rule as well.

I still prefer the boolean expression solution, but not sure how to implement that solution without the caveat of the possible "false". But your solution of counting can be the best approach in most situations. thanks.

---

<div class="post-metadata">

**Author:** ![Colin](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/colin/32/17040_2.png) [@Colin](https://discourse.nodered.org/u/Colin)\
**Post date:** [11 December 2023 21:51 UTC](https://discourse.nodered.org/t/what-is-the-correct-way-to-use-jsonata-inside-a-switch-node-with-has-key-rule/83616/11 "2023-12-11T21:51:16Z")

</div>

> [@alwinter](#):
>
> not sure how to implement that solution without the caveat of the possible "false"

It would also fail if the value were zero.

---

<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 December 2023 22:00 UTC](https://discourse.nodered.org/t/what-is-the-correct-way-to-use-jsonata-inside-a-switch-node-with-has-key-rule/83616/12 "2023-12-11T22:00:23Z")

</div>

Jbudd's solution would also fail if keyOne or keyTwo were an empty object or array. So not really a solution.

[edit]  
Here is a boolean solution to.

```auto
$not(false in ["keyOne","keyTwo"].($ in $keys($$.payload)))

```

---

<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 December 2023 22:01 UTC](https://discourse.nodered.org/t/what-is-the-correct-way-to-use-jsonata-inside-a-switch-node-with-has-key-rule/83616/13 "2023-12-11T22:01:56Z")

</div>

Well I dunno about you lot but i'd do it with two switch nodes in series.  
One testing for keyOne and the other for keyTwo 😀

And if it's just a simplified example, you really want to test for many keys, I'd put all the switch nodes on another flow with link-in and link-return.

I'm glad I mentioned my version was faulty before everyone else did!

---

<div class="post-metadata">

**Author:** ![alwinter](https://avatars.discourse-cdn.com/v4/letter/a/df788c/32.png) [@alwinter](https://discourse.nodered.org/u/alwinter)\
**Post date:** [12 December 2023 00:07 UTC](https://discourse.nodered.org/t/what-is-the-correct-way-to-use-jsonata-inside-a-switch-node-with-has-key-rule/83616/14 "2023-12-12T00:07:25Z")

</div>

thanks for your response, and all other people for helping out.

Actually i was testing something similar before your message.

`(("keyOne" in $keys($$.payload)) and ("keyTwo" in $keys($$.payload)))`

but your solution seems more elegant.

I never tried jsonata before so it was good to test things out.

---

<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:** [26 December 2023 00:08 UTC](https://discourse.nodered.org/t/what-is-the-correct-way-to-use-jsonata-inside-a-switch-node-with-has-key-rule/83616/15 "2023-12-26T00:08:16Z")

</div>

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