# If/else in JSONata expressions

**URL:** <https://discourse.nodered.org/t/if-else-in-jsonata-expressions/26194>\
**Category:** General\
**Created:** [6 May 2020 22:16 UTC](https://discourse.nodered.org/t/if-else-in-jsonata-expressions/26194 "2020-05-06T22:16:46Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![iStitch07](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/istitch07/32/21390_2.png) [@iStitch07](https://discourse.nodered.org/u/iStitch07)\
**Post date:** [6 May 2020 22:16 UTC](https://discourse.nodered.org/t/if-else-in-jsonata-expressions/26194/1 "2020-05-06T22:16:47Z")

</div>

Hello. Noob question, but... )  
it's posible to use if/else in JSONata expressions?

I have this expression.

```auto
{
   "brightness_pct" : payload.brightness,
   "hs_color" : [payload.hue, payload.saturation]

}

```

In rare case in msg not exist payload.hue and/or payload.saturation. And in this case I need to use just

```auto
{
    "brightness_pct" : payload.brightness
}

```

I try to find examples, but unsuccessful  
Thanks

---

<div class="post-metadata">

**Author:** ![Andrei](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/andrei/32/10446_2.png) [@Andrei](https://discourse.nodered.org/u/Andrei)\
**Post date:** [7 May 2020 01:46 UTC](https://discourse.nodered.org/t/if-else-in-jsonata-expressions/26194/2 "2020-05-07T01:46:24Z")

</div>

Welcome to the forum @iStitch07,

Good question. You probably know that there is the [ternary conditional operator](https://docs.jsonata.org/other-operators) in jsonata. However the trick part of the question is:

> In rare case in msg not exist payload.hue and/or payload.saturation

The bottom line is that jsonata can only operate on a valid JSON string.

If `payload.hue` does not exist and `payload,saturation` equals, lets say 5, what `hs_color` will looks like ?

[, 5] or [null , 5] or [undefined,5] ?

---

<div class="post-metadata">

**Author:** ![nlecaude](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/nlecaude/32/25_2.png) [@nlecaude](https://discourse.nodered.org/u/nlecaude)\
**Post date:** [7 May 2020 03:28 UTC](https://discourse.nodered.org/t/if-else-in-jsonata-expressions/26194/3 "2020-05-07T03:28:19Z")

</div>

this works for me:

```auto
{
   "brightness_pct" : payload.brightness,
   "hs_color" : payload.hue and payload.saturation ? [payload.hue, payload.saturation] 
}

```

Update:

```auto
{
   "brightness_pct" : payload.brightness,
   "hs_color" : payload.hue != null and payload.saturation != null ? [payload.hue, payload.saturation] 
}

```

This is actually better as it will work if hue or saturation = 0

---

<div class="post-metadata">

**Author:** ![iStitch07](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/istitch07/32/21390_2.png) [@iStitch07](https://discourse.nodered.org/u/iStitch07)\
**Post date:** [7 May 2020 06:32 UTC](https://discourse.nodered.org/t/if-else-in-jsonata-expressions/26194/4 "2020-05-07T06:32:00Z")

</div>

If at least one or both values don’t exist, I need to skip full line, include “hs\_color” too

---

<div class="post-metadata">

**Author:** ![iStitch07](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/istitch07/32/21390_2.png) [@iStitch07](https://discourse.nodered.org/u/iStitch07)\
**Post date:** [7 May 2020 06:35 UTC](https://discourse.nodered.org/t/if-else-in-jsonata-expressions/26194/5 "2020-05-07T06:35:04Z")

</div>

Looks great, I will try this, because I need to complete skip this line if one or both values not exist

```auto

{
   "brightness_pct" : payload.brightness,
   payload.hue != null and payload.saturation != null ? "hs_color": [payload.hue, payload.saturation] 
}

```

Update:  
But coma in first line will be cause of error if I skip the second line

Update2: my variant got a syntax error. Your variant pass the syntax validation, but will cause error with empty “hs\_color” service calling ☹

---

<div class="post-metadata">

**Author:** ![Steve-Mcl](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/steve-mcl/32/4826_2.png) [@Steve-Mcl](https://discourse.nodered.org/u/Steve-Mcl)\
**Post date:** [7 May 2020 07:29 UTC](https://discourse.nodered.org/t/if-else-in-jsonata-expressions/26194/6 "2020-05-07T07:29:54Z")

</div>

@iStitch07 is this a purely academic question?

If not and you really need to solve this then why not just defer to a function node. The logic you require is quite simple to achieve in standard js.

---

<div class="post-metadata">

**Author:** ![iStitch07](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/istitch07/32/21390_2.png) [@iStitch07](https://discourse.nodered.org/u/iStitch07)\
**Post date:** [7 May 2020 07:57 UTC](https://discourse.nodered.org/t/if-else-in-jsonata-expressions/26194/7 "2020-05-07T07:57:33Z")

</div>

No, it’s not academic question. I try to optimize this flow

 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/4/8/48a1afc8d6563ef3af3a146a0d3e8613b18accd6.jpeg)

If I will add additional function node, I will need to add and another service calling node. And it’s not “pretty” 🙂

 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/b/7/b79da0057c43cc520160ce1fe2aead84702d5be1.jpeg)

---

<div class="post-metadata">

**Author:** ![Steve-Mcl](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/steve-mcl/32/4826_2.png) [@Steve-Mcl](https://discourse.nodered.org/u/Steve-Mcl)\
**Post date:** [7 May 2020 08:03 UTC](https://discourse.nodered.org/t/if-else-in-jsonata-expressions/26194/8 "2020-05-07T08:03:46Z")

</div>

Um, no? Confused!

Whatever you want to do in jasonata you can do +more in a function node.

Just return the msg with correct properties/values surely? Not sure why you would need to add 2 outputs and 2 blue nodes (whatever they are)?

---

<div class="post-metadata">

**Author:** ![iStitch07](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/istitch07/32/21390_2.png) [@iStitch07](https://discourse.nodered.org/u/iStitch07)\
**Post date:** [7 May 2020 08:10 UTC](https://discourse.nodered.org/t/if-else-in-jsonata-expressions/26194/9 "2020-05-07T08:10:01Z")

</div>

I’m not sure and will try

 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/4/8/48fa066ce5866b098577e3b306dd1d53d26a0c90.jpeg)

If it possible to create valid json in function node and pass it in payload to data field in service call node - its will be answer

---

<div class="post-metadata">

**Author:** ![Steve-Mcl](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/steve-mcl/32/4826_2.png) [@Steve-Mcl](https://discourse.nodered.org/u/Steve-Mcl)\
**Post date:** [7 May 2020 08:21 UTC](https://discourse.nodered.org/t/if-else-in-jsonata-expressions/26194/10 "2020-05-07T08:21:35Z")

</div>

> [@iStitch07](#):
>
> If it possible to create valid json in function node and pass it in payload to data field in service call node - its will be answer

You don't create JSON really (JSON is a string representation of a JavaScript object)

You build a property in the msg (usually payload) then send it onwards.

E.g.

```auto
let x;
if(msg.something) { 
 x = msg.thisval
} else {
  x = msg.thatval
}
msg.payload = {
  brightness : x
}
return msg;

```

In fact, you can probably just set a new property in the msg then set that data property to the same msg.prop you invent

E.g.

```auto
if(msg.something) { 
 msg.brightness = msg.thisval
} else {
  msg.brightness = msg.thatval
}
return msg;

```

Then change the `data` option to `msg` and enter `brightness`

---

<div class="post-metadata">

**Author:** ![iStitch07](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/istitch07/32/21390_2.png) [@iStitch07](https://discourse.nodered.org/u/iStitch07)\
**Post date:** [7 May 2020 08:34 UTC](https://discourse.nodered.org/t/if-else-in-jsonata-expressions/26194/11 "2020-05-07T08:34:05Z")

</div>

But we return to begin.  
I already do something like this in function node

```auto

var brg_name = msg.topic + '.brightness';
var sat_name = msg.topic + '.saturation';
var hue_name = msg.topic + '.hue'

var new_val = {};

if(msg.payload.Brightness >= 0) {
    new_val.brightness = msg.payload.Brightness;
    flow.set(brg_name, msg.payload.Brightness);
    new_val.saturation = flow.get(sat_name);
    new_val.hue = flow.get(hue_name);
}

if(msg.payload.Hue >= 0) {
    new_val.brightness = flow.get(brg_name);
    new_val.saturation = flow.get(sat_name);
    new_val.hue = msg.payload.Hue;
    flow.set(hue_name, msg.payload.Hue);
}

if(msg.payload.Saturation >= 0) {
    new_val.brightness = flow.get(brg_name);
    new_val.saturation = msg.payload.Saturation;
    flow.set(sat_name, msg.payload.Saturation);
    new_val.hue = flow.get(hue_name);  
}

msg.payload = new_val;
return msg;

```

But in service call node I need to set param for service calling

If I have only brightness in payload, then I need to call service

```auto
{
   "brightness_pct" : payload.brightness
}

```

Else, if I have payload.hue AND payload.saturation, I need to call service with this param

```auto
{
   "brightness_pct" : payload.brightness,
   "hs_color" : [payload.hue, payload.saturation]

}

```

---

<div class="post-metadata">

**Author:** ![Steve-Mcl](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/steve-mcl/32/4826_2.png) [@Steve-Mcl](https://discourse.nodered.org/u/Steve-Mcl)\
**Post date:** [7 May 2020 08:47 UTC](https://discourse.nodered.org/t/if-else-in-jsonata-expressions/26194/12 "2020-05-07T08:47:59Z")

</div>

Yeah so do that in a function node.

I really don't understand why you don't just do exactly what you're saying

In the function node, just do the logic & update a property in msg (any property you desire) with either  
`{ "brightness_pct" : msg.payload.brightness }`  
or  
`{ "brightness_pct" : payload.brightness, "hs_color" : [msg.payload.hue, msg.payload.saturation] }`

Then set the data option in the blue node to `msg` type and the matching property name

The blue node will recieve the data you send. No need for jsonata.

An I missing something?

---

<div class="post-metadata">

**Author:** ![Steve-Mcl](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/steve-mcl/32/4826_2.png) [@Steve-Mcl](https://discourse.nodered.org/u/Steve-Mcl)\
**Post date:** [7 May 2020 09:20 UTC](https://discourse.nodered.org/t/if-else-in-jsonata-expressions/26194/13 "2020-05-07T09:20:43Z")

</div>

What node is that blue node?

the [one i looked](https://flows.nodered.org/node/node-red-contrib-home-assistant) at doesnt permit JSONata in the `Data` field but it does permit you to send `data` in `msg.payload.data`

> If the incoming message has a `payload` property with `domain` , `service` set it will override any config values if set.  
> If the incoming message has a `payload.data` that is an object or parseable into an object these properties will be **merged** with any config values set.

So if that is the same for your node then something like this might work...

```js

//first add a data property and set brightness_pct to msg.payload.brightness
msg.payload.data = {
   "brightness_pct" : msg.payload.brightness;
}

//next, if msg.payload.hue && payload.saturation are present, add hs_color property
if(msg.payload.hue && payload.saturation) {
 msg.payload.data.hs_color = [msg.payload.hue, msg.payload.saturation]; 
}

return msg;

```

---

<div class="post-metadata">

**Author:** ![iStitch07](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/istitch07/32/21390_2.png) [@iStitch07](https://discourse.nodered.org/u/iStitch07)\
**Post date:** [7 May 2020 09:29 UTC](https://discourse.nodered.org/t/if-else-in-jsonata-expressions/26194/14 "2020-05-07T09:29:57Z")

</div>

I was try change function node with adding this block

```auto
if(new_val.brightness && (!new_val.hue || !new_val.saturation) ) {
    new_val.params = '{ "brightness_pct" : ' + new_val.brightness + ' }';
} else {
    new_val.params = '{ "brightness_pct" : ' + new_val.brightness + ', "hs_color" : [' + new_val.hue + ', ' + new_val.saturation + '] }';
}

```

After add to blue node in data field - {{payload.params}}  
And got a error

```auto
Call-service API error. Error Message: extra keys not allowed @ data['0']

```

But in debug all look fine

```auto
{"brightness":100,"saturation":100,"hue":234,"params":"{ \"brightness_pct\" : 100, \"hs_color\" : [234, 100] }"}

```

---

<div class="post-metadata">

**Author:** ![iStitch07](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/istitch07/32/21390_2.png) [@iStitch07](https://discourse.nodered.org/u/iStitch07)\
**Post date:** [7 May 2020 09:32 UTC](https://discourse.nodered.org/t/if-else-in-jsonata-expressions/26194/15 "2020-05-07T09:32:47Z")

</div>

Sorry, I’m little slow because working on iPad now 🙂  
Blue node its home assistant call service node. I will try do use payload.data

---

<div class="post-metadata">

**Author:** ![Steve-Mcl](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/steve-mcl/32/4826_2.png) [@Steve-Mcl](https://discourse.nodered.org/u/Steve-Mcl)\
**Post date:** [7 May 2020 09:34 UTC](https://discourse.nodered.org/t/if-else-in-jsonata-expressions/26194/16 "2020-05-07T09:34:20Z")

</div>

> [@iStitch07](#):
>
> Blue node its home assistant call service node

[which one](https://flows.nodered.org/search?term=assistant&type=node)?

---

<div class="post-metadata">

**Author:** ![iStitch07](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/istitch07/32/21390_2.png) [@iStitch07](https://discourse.nodered.org/u/iStitch07)\
**Post date:** [7 May 2020 09:35 UTC](https://discourse.nodered.org/t/if-else-in-jsonata-expressions/26194/17 "2020-05-07T09:35:13Z")

</div>

node-red-contrib-home-assistant-websocket

---

<div class="post-metadata">

**Author:** ![Steve-Mcl](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/steve-mcl/32/4826_2.png) [@Steve-Mcl](https://discourse.nodered.org/u/Steve-Mcl)\
**Post date:** [7 May 2020 09:37 UTC](https://discourse.nodered.org/t/if-else-in-jsonata-expressions/26194/18 "2020-05-07T09:37:43Z")

</div>

Why are you doing JSON strings?

Did you try the function I wrote out for you?

---

<div class="post-metadata">

**Author:** ![Steve-Mcl](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/steve-mcl/32/4826_2.png) [@Steve-Mcl](https://discourse.nodered.org/u/Steve-Mcl)\
**Post date:** [7 May 2020 09:40 UTC](https://discourse.nodered.org/t/if-else-in-jsonata-expressions/26194/19 "2020-05-07T09:40:43Z")

</div>

The help says...  
 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/e/e/eec435829b5dfc438bccc4d96ed1918606cd4223.png)

So try the function I stated & pass an object (not JSON)

EDIT, to allow hue 0 and saturation 0 values...

```auto
//first add a data property and set brightness_pct to msg.payload.brightness
msg.payload.data = {
   "brightness_pct" : msg.payload.brightness;
}

//next, if msg.payload.hue && payload.saturation are present, add hs_color property
if(msg.payload.hasOwnProperty("hue") && payload.hasOwnProperty("saturation")) {
 msg.payload.data.hs_color = [msg.payload.hue, msg.payload.saturation]; 
}

return msg;

```

And just leave the Data field blank.

---

<div class="post-metadata">

**Author:** ![iStitch07](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/istitch07/32/21390_2.png) [@iStitch07](https://discourse.nodered.org/u/iStitch07)\
**Post date:** [7 May 2020 09:48 UTC](https://discourse.nodered.org/t/if-else-in-jsonata-expressions/26194/20 "2020-05-07T09:48:07Z")

</div>

Easy, easy - its my first week with node-red 🙂 I still learning 🙂

I will try your code from last post

[Next page](https://discourse.nodered.org/t/if-else-in-jsonata-expressions/26194.md?page=2)
