# Beginner questions on IF expressions and wildcard usage in function node

**URL:** <https://discourse.nodered.org/t/beginner-questions-on-if-expressions-and-wildcard-usage-in-function-node/80999>\
**Category:** General\
**Created:** [3 September 2023 11:43 UTC](https://discourse.nodered.org/t/beginner-questions-on-if-expressions-and-wildcard-usage-in-function-node/80999 "2023-09-03T11:43:38Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![AleXSR700](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/alexsr700/32/41161_2.png) [@AleXSR700](https://discourse.nodered.org/u/AleXSR700)\
**Post date:** [3 September 2023 11:43 UTC](https://discourse.nodered.org/t/beginner-questions-on-if-expressions-and-wildcard-usage-in-function-node/80999/1 "2023-09-03T11:43:39Z")

</div>

Hello everyone,  
I am trying to step by step build a small MQTT filter flow.

I have my MQTT input all set up and can receive messages and I can "filter" using a function node with e.g.

```auto
var msg = { payload: msg.payload.ENERGY['Total'] };
return msg;

```

_ **First issue** _ 🙂  
However, if a payload does not have the key 'Total' I get the following error message

```auto
TypeError: Cannot read properties of undefined (reading 'Total')

```

So I tried ensuring that the key exists, but it is also throws an error.  
Tried

```auto
if ('Total' in msg.payload.ENERGY) {
    var msg = { payload: msg.payload.ENERGY['Total'] };
    return msg;
}

```

and

```auto
if (msg.payload.hasOwnProperty('Total')) {
    var msg = { payload: msg.payload.ENERGY['Total'] };
    return msg;
}

```

_ **Second issue** _ 🙂  
I would also like to be able to use wildcards, but my syntax seems wrong and I cannot find the solution.  
Here I am trying to find all payloads that contain a key with "ATC" in its name

```auto
payload: msg.payload+'.[ATC*]'

```

Also tried `#` and `+`instead of \* (because those can be used e.g. when subscribing to an MQTT topic).

Thank you for your support 🙂  
Alex

EDIT1:  
Also unsuccessfully tried

```auto
if (msg.payload.ENERGY['Power'] !== undefined) {
    var msg = { payload: msg.payload.ENERGY['Power'] };
    return msg;
}

```

because apparently this is faster than the "in" or "hasOwnProperty" approach ( [arrays - Checking if a key exists in a JavaScript object? - Stack Overflow](https://stackoverflow.com/a/22074727/16686206) )

EDIT2:  
I think I may have solved my first issue:

> [@Beginner questions on IF expressions and wildcard usage in function node](https://discourse.nodered.org/t/beginner-questions-on-if-expressions-and-wildcard-usage-in-function-node/80999/7):
>
> Okay, I got a step closer. I cannot check for the key directly but first need to ensure that the object is actually present. if (msg.payload.ENERGY !== undefined) { var msg = { payload: msg.payload.ENERGY['Power'] }; return msg; } EDIT: And in a second step then check the key. This seems to work: if (msg.payload.ENERGY !== undefined) { if (msg.payload.ENERGY['Power'] !== undefined) { var msg = { payload: msg.payload.ENERGY['Power'] }; return msg; } } Now I need…

EDIT3:  
And @Colin solved the second issue 🙌

> [@Beginner questions on IF expressions and wildcard usage in function node](https://discourse.nodered.org/t/beginner-questions-on-if-expressions-and-wildcard-usage-in-function-node/80999/30):
>
> Or using filter [{"id":"3f53197d243846c3","type":"inject","z":"bdd7be38.d3b55","name":"With ATC","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"{\"mac\":\"a4c1380d5c0c\",\"Temperature\":21.6,\"Humidity\":64.7,\"DewPoint\":14.7,\"Btn\":0,\"Battery\":37,\"ATC1\":\"this is the value of ATC1\",\"RSSI\":-64}","payloadType":"json","x":700,"y":140,"wires":[["853adc83d89cddaa"]]},{"id":"3586ec0a6edd8630","type":"inject","z"…

> [@Beginner questions on IF expressions and wildcard usage in function node](https://discourse.nodered.org/t/beginner-questions-on-if-expressions-and-wildcard-usage-in-function-node/80999/32):
>
> The key is in element so you can use matchingKeys.forEach((element) =\> node.send({topic: element, payload: msg.payload[element]}))

---

<div class="post-metadata">

**Author:** ![dynamicdave](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/dynamicdave/32/96_2.png) [@dynamicdave](https://discourse.nodered.org/u/dynamicdave)\
**Post date:** [3 September 2023 11:59 UTC](https://discourse.nodered.org/t/beginner-questions-on-if-expressions-and-wildcard-usage-in-function-node/80999/2 "2023-09-03T11:59:37Z")

</div>

Try this...

> [@AleXSR700](#):
>
> ```auto
> var msg.payload = msg.payload.ENERGY['Total'];
> return msg;
> 
> ```

ENERGY total should appear in msg.payload in the next part of your flow.

Oops - just re-read your original post - I doubt if the above is wwhat you want (sorry).

---

<div class="post-metadata">

**Author:** ![AleXSR700](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/alexsr700/32/41161_2.png) [@AleXSR700](https://discourse.nodered.org/u/AleXSR700)\
**Post date:** [3 September 2023 12:02 UTC](https://discourse.nodered.org/t/beginner-questions-on-if-expressions-and-wildcard-usage-in-function-node/80999/3 "2023-09-03T12:02:46Z")

</div>

Thank you Dave,  
but I think your approach is essentially what I initially did and which does produce the correct output IF that key exists.  
I am trying to prevent errors by first checking if the key exists and only then creating the new msg.

---

<div class="post-metadata">

**Author:** ![dynamicdave](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/dynamicdave/32/96_2.png) [@dynamicdave](https://discourse.nodered.org/u/dynamicdave)\
**Post date:** [3 September 2023 12:06 UTC](https://discourse.nodered.org/t/beginner-questions-on-if-expressions-and-wildcard-usage-in-function-node/80999/4 "2023-09-03T12:06:08Z")

</div>

Umm - this is what I would have tried (just like your attempt).  
Not near a PC so can't try the code at the moment

```auto
if ('Total' in msg.payload.ENERGY) {
  console.log('Total exists in msg.payload.ENERGY');
} else {
  console.log('Total does not exist in msg.payload.ENERGY');
}

```

---

<div class="post-metadata">

**Author:** ![dynamicdave](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/dynamicdave/32/96_2.png) [@dynamicdave](https://discourse.nodered.org/u/dynamicdave)\
**Post date:** [3 September 2023 12:08 UTC](https://discourse.nodered.org/t/beginner-questions-on-if-expressions-and-wildcard-usage-in-function-node/80999/5 "2023-09-03T12:08:08Z")

</div>

Sorry - this was meant for you not me.

> [@dynamicdave](#):
>
> Umm - this is what I would have tried (just like your attempt).  
> Not near a PC so can't try the code at the moment
> 
> ```auto
> if ('Total' in msg.payload.ENERGY) {
> console.log('Total exists in msg.payload.ENERGY');
> } else {
> console.log('Total does not exist in msg.payload.ENERGY');
> }
> 
> ```

---

<div class="post-metadata">

**Author:** ![AleXSR700](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/alexsr700/32/41161_2.png) [@AleXSR700](https://discourse.nodered.org/u/AleXSR700)\
**Post date:** [3 September 2023 12:13 UTC](https://discourse.nodered.org/t/beginner-questions-on-if-expressions-and-wildcard-usage-in-function-node/80999/6 "2023-09-03T12:13:33Z")

</div>

> [@dynamicdave](#):
>
> ```auto
> if ('Total' in msg.payload.ENERGY) {
> console.log('Total exists in msg.payload.ENERGY');
> } else {
> console.log('Total does not exist in msg.payload.ENERGY');
> }
> 
> ```

Unfortunately same as with my approach in first post. ☹

```auto
TypeError: Cannot use 'in' operator to search for 'Total' in undefined

```

---

<div class="post-metadata">

**Author:** ![AleXSR700](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/alexsr700/32/41161_2.png) [@AleXSR700](https://discourse.nodered.org/u/AleXSR700)\
**Post date:** [3 September 2023 12:18 UTC](https://discourse.nodered.org/t/beginner-questions-on-if-expressions-and-wildcard-usage-in-function-node/80999/7 "2023-09-03T12:18:20Z")

</div>

Okay, I got a step closer.  
I cannot check for the key directly but first need to ensure that the object is actually present.

```auto
if (msg.payload.ENERGY !== undefined) {
    var msg = { payload: msg.payload.ENERGY['Power'] };
    return msg;
}

```

EDIT:  
And in a second step then check the key.

This seems to work:

```auto
if (msg.payload.ENERGY !== undefined) {
    if (msg.payload.ENERGY['Power'] !== undefined) {
        var msg = { payload: msg.payload.ENERGY['Power'] };
        return msg;
}
}

```

Now I need to figure out the wildcard problem.

---

<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:** [3 September 2023 12:35 UTC](https://discourse.nodered.org/t/beginner-questions-on-if-expressions-and-wildcard-usage-in-function-node/80999/8 "2023-09-03T12:35:39Z")

</div>

For the record, you don't need to use `['Power']`. You only need to do that if the property name (Power) has special characters in it. So you can use `msg.payload.ENERGY.Power`.

---

<div class="post-metadata">

**Author:** ![AleXSR700](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/alexsr700/32/41161_2.png) [@AleXSR700](https://discourse.nodered.org/u/AleXSR700)\
**Post date:** [3 September 2023 12:36 UTC](https://discourse.nodered.org/t/beginner-questions-on-if-expressions-and-wildcard-usage-in-function-node/80999/9 "2023-09-03T12:36:46Z")

</div>

I am using the Total in a second step to ensure that I do not get an error if the object ENERGY exists but does not have a key named Total.  
Or do you mean that this is redundant because the error is only linked to missing object and not to missing keys?

---

<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:** [3 September 2023 12:40 UTC](https://discourse.nodered.org/t/beginner-questions-on-if-expressions-and-wildcard-usage-in-function-node/80999/10 "2023-09-03T12:40:01Z")

</div>

Sorry, I had multiple typos in my post, now corrected. I just meant that wherever you use `['Power']` you can use `.Power`

---

<div class="post-metadata">

**Author:** ![AleXSR700](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/alexsr700/32/41161_2.png) [@AleXSR700](https://discourse.nodered.org/u/AleXSR700)\
**Post date:** [3 September 2023 12:44 UTC](https://discourse.nodered.org/t/beginner-questions-on-if-expressions-and-wildcard-usage-in-function-node/80999/11 "2023-09-03T12:44:10Z")

</div>

For the wildcard problem I think I need to use regular expressions, but I seem to be doing it wrong.

```auto
if (msg.payload./ATC/ !== undefined) {
    var msg = { payload: msg.payload./ATC/ };
    return msg;
}

```

This should be all payloads that contain an object starting with "ATC", but I get a syntax error.

---

<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:** [3 September 2023 12:48 UTC](https://discourse.nodered.org/t/beginner-questions-on-if-expressions-and-wildcard-usage-in-function-node/80999/12 "2023-09-03T12:48:16Z")

</div>

Does the payload contain multiple properties or will it only ever contain one, such as ATC123?  
Also is the ATC always at the start?

---

<div class="post-metadata">

**Author:** ![AleXSR700](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/alexsr700/32/41161_2.png) [@AleXSR700](https://discourse.nodered.org/u/AleXSR700)\
**Post date:** [3 September 2023 12:50 UTC](https://discourse.nodered.org/t/beginner-questions-on-if-expressions-and-wildcard-usage-in-function-node/80999/13 "2023-09-03T12:50:12Z")

</div>

The payload can contain all kinds of properties (if I am using the word 'properties' correctly).  
Placement could theoretically vary but it is usually not at the start.

Here is an example payload:

```auto
{"Time":"2023-09-03T14:48:50","ATC0d5c0c":{"mac":"a4c1380d5c0c","Temperature":21.6,"Humidity":66.2,"DewPoint":15,"Btn":0,"Battery":37,"RSSI":-68},"ATC8f1b4f":{"mac":"a4c1388f1b4f","Temperature":21.9,"Humidity":62.9,"DewPoint":14.5,"Btn":0,"Battery":69,"RSSI":-62},"TempUnit":"C"}

```

---

<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:** [3 September 2023 12:52 UTC](https://discourse.nodered.org/t/beginner-questions-on-if-expressions-and-wildcard-usage-in-function-node/80999/14 "2023-09-03T12:52:32Z")

</div>

Here is a function which detects if msg.payload has an element whose key begins with "ATC".  
I don't know how efficient it is!

```auto
for (let key in msg.payload) {
    node.warn (key)
    if (/^ATC/.test(key)) {
        node.warn (key + " begins with ATC")
        node.warn ("It's value is " + msg.payload[key])
    }
}
   
return msg;

```

---

<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:** [3 September 2023 13:06 UTC](https://discourse.nodered.org/t/beginner-questions-on-if-expressions-and-wildcard-usage-in-function-node/80999/15 "2023-09-03T13:06:39Z")

</div>

In that case you need to test all the properties (or keys) to see if any of them match.

> [@AleXSR700](#):
>
> Placement could theoretically vary but it is usually not at the start.

I didn't mean if it is the first property, I meant if then name starts with ATC, or if the ATC could be anywhere in the property name.

Assuming that it is always at the start then you can iterate through the properties (or keys) using something like

```auto
Object.keys(msg.payload).forEach((element) => {
  if (element.startsWith("ATC")) {
    msg.payload = msg.payload[element]
    node.send(msg)
  }
})

```

---

<div class="post-metadata">

**Author:** ![AleXSR700](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/alexsr700/32/41161_2.png) [@AleXSR700](https://discourse.nodered.org/u/AleXSR700)\
**Post date:** [3 September 2023 13:25 UTC](https://discourse.nodered.org/t/beginner-questions-on-if-expressions-and-wildcard-usage-in-function-node/80999/16 "2023-09-03T13:25:46Z")

</div>

Your code works, thank you!

But I am a bit surprised that I have to test all keys one by one/looping through each. Why is that?

When I use

```auto
if (msg.payload.ENERGY['Power'] !== undefined) {

```

this also checks if any of the keys matches 'Power'. Would the same approach not be possible by ending the `msg.payload.ENERGY` with a regular expression for "starts with ATC"?  
`msg.payload.ENERGY + regular expression for "starts with ATC"`

EDIT1:  
So, this did not work

```auto
if (msg.payload.startsWith("ATC") !== undefined) {
    var msg = { payload: msg.payload.startsWith("ATC") };
    return msg;
}

```

`TypeError: msg.payload.startsWith is not a function`

---

<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:** [3 September 2023 14:07 UTC](https://discourse.nodered.org/t/beginner-questions-on-if-expressions-and-wildcard-usage-in-function-node/80999/17 "2023-09-03T14:07:05Z")

</div>

> [@AleXSR700](#):
>
> _ **Second issue** _ 🙂  
> I would also like to be able to use wildcards, but my syntax seems wrong and I cannot find the solution.  
> Here I am trying to find all payloads that contain a key with "ATC" in its name
> 
> ```auto
> payload: msg.payload+'.[ATC*]'
> 
> ```
> 
> Also tried `#` and `+`instead of \* (because those can be used e.g. when subscribing to an MQTT topic).

Firstly, you mixed dot with bracket notation. Secondly, you cannot use wildcards in object or array selectors.

What you can do is to use a `filter`. Please do some reading on the filter function in JavaScript.

* * *

[Array.prototype.filter() - JavaScript | MDN (mozilla.org)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter)

Also note that `filter` is an Array function. If your payload is an object rather than an array, you will need to convert using `Object.keys`. That gets you an array of the keys that you can filter and pass into a loop. Alternatively, if the key is also represented in the objects values, you can use `Object.values` and filter more directly.

---

<div class="post-metadata">

**Author:** ![AleXSR700](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/alexsr700/32/41161_2.png) [@AleXSR700](https://discourse.nodered.org/u/AleXSR700)\
**Post date:** [3 September 2023 14:07 UTC](https://discourse.nodered.org/t/beginner-questions-on-if-expressions-and-wildcard-usage-in-function-node/80999/18 "2023-09-03T14:07:11Z")

</div>

> [@Colin](#):
>
> Assuming that it is always at the start then you can iterate through the properties (or keys) using something like
> 
> ```auto
> Object.keys(msg.payload).forEach((element) => {
> if (element.startsWith("ATC")) {
> msg.payload = msg.payload[element]
> node.send(msg)
> }
> })
> 
> ```

Follow up question.  
The output of this is e.g.

```auto
{"mac":"a4c1380d5c0c","Temperature":21.6,"Humidity":64.7,"DewPoint":14.7,"Btn":0,"Battery":37,"RSSI":-64}

```

but there is also a payload `undefined`.  
So the filtering is not quite working correctly yet.

---

<div class="post-metadata">

**Author:** ![AleXSR700](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/alexsr700/32/41161_2.png) [@AleXSR700](https://discourse.nodered.org/u/AleXSR700)\
**Post date:** [3 September 2023 14:13 UTC](https://discourse.nodered.org/t/beginner-questions-on-if-expressions-and-wildcard-usage-in-function-node/80999/19 "2023-09-03T14:13:09Z")

</div>

MQTT node is set to output parsed JSON object. So it is always a parsed JSON object that is being processed.

I was unsuccessful with the filter function also.

```auto
var msg = { payload: msg.payload.filter(function (str) { return str.includes('ATC'); }) };
return msg;

```

Gives me error

```auto
TypeError: msg.payload.filter is not a function

```

But msg.payload is my array, is it not?

---

<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:** [3 September 2023 14:23 UTC](https://discourse.nodered.org/t/beginner-questions-on-if-expressions-and-wildcard-usage-in-function-node/80999/20 "2023-09-03T14:23:54Z")

</div>

> [@AleXSR700](#):
>
> So the filtering is not quite working correctly yet.

Show us the full function please.

It is worth finding why it does not work, but @TotallyInformation is correct, using filter would probably be better.

> [@AleXSR700](#):
>
> But I am a bit surprised that I have to test all keys one by one/looping through each. Why is that?
> 
> When I use
> 
> ```auto
> if (msg.payload.ENERGY['Power'] !== undefined) {
> 
> ```
> 
> this also checks if any of the keys matches 'Power'.

It doesn't check if any of the keys match, it just goes to the one called Power and tries to get it. Only then does it realise that it does not exist.

It is like the difference between phoning extension 123 and seeing if anyone replies, rather than asking if any of the 12x numbers reply. In the first case (extension 123 or key Power) you just try it, for the second (12x or ATX???) the only way to know is to try them all.

[Next page](https://discourse.nodered.org/t/beginner-questions-on-if-expressions-and-wildcard-usage-in-function-node/80999.md?page=2)
