# Change node - can this be done?

**URL:** <https://discourse.nodered.org/t/change-node-can-this-be-done/85214>\
**Category:** General\
**Created:** [5 February 2024 10:59 UTC](https://discourse.nodered.org/t/change-node-can-this-be-done/85214 "2024-02-05T10:59:38Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![Trying\_to\_learn](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/trying_to_learn/32/28400_2.png) [@Trying\_to\_learn](https://discourse.nodered.org/u/Trying_to_learn)\
**Post date:** [5 February 2024 10:59 UTC](https://discourse.nodered.org/t/change-node-can-this-be-done/85214/1 "2024-02-05T10:59:38Z")

</div>

Sorry folks, another _Today's dumb question_.

Recent events have had me going in circles with the `change` node.

Base line of the question is this:

Say I am expecting a `number` value to come in and for what ever reason it is `text`.

(to clarify)  
Say I am expecting `30` and get 30.

My `change` node has this in it:

Here's the node for perfect clarity:

```auto
[
    {
        "id": "44e43511439631d5",
        "type": "change",
        "z": "aad05e94.e66068",
        "name": "",
        "rules": [
            {
                "t": "set",
                "p": "payload",
                "pt": "msg",
                "to": "msg.payload * 1000 * 60",
                "tot": "jsonata"
            },
            {
                "t": "set",
                "p": "topic",
                "pt": "msg",
                "to": "delay",
                "tot": "str"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 1070,
        "y": 2930,
        "wires": [
            [
                "2409a9f98804fd88",
                "9a949d29ccd6c117"
            ]
        ]
    }
]

```

So:  
set `msg.payload` to  
`J: msg.payload * 1000 * 60`

Basically making the 30 into `30` minutes. (Yes?)  
I did the maths the longer way only for ..... clarity?

Anyway.

So I get a 30 and not a `30` coming in.

I can't do:  
`J: parseInt(msgmpayload) * 1000 * 60`  
can I.

I'm suspicious (well, I've tested it and it doesn't work) it can't be done.

But if there is a _trick_ that would allow that it would be handy to know.

Back to what I've just said about the input.

# **YES**

It is sloppy programming.

It was an example that is a good example to ask the question.

# **NO**

I do NOT want to promote such bad practices. But to me the question is there begging.

---

<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:** [5 February 2024 12:02 UTC](https://discourse.nodered.org/t/change-node-can-this-be-done/85214/2 "2024-02-05T12:02:41Z")

</div>

Doesn't $number(msg.payload) work?

![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/6/7/67e7448b3e6f1a84d8bd02dcce6b30677a580cf9.png)

---

<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:** [5 February 2024 12:23 UTC](https://discourse.nodered.org/t/change-node-can-this-be-done/85214/3 "2024-02-05T12:23:00Z")

</div>

@Trying_to_learn  
Do not use msg.payload in a JSONata expression.  
either  
$$.payload  
or just  
payload.  
Compatibility mode is deprecated

All the JSONata functions are listed in the JSONata Expression editor, function reference.

---

<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:** [5 February 2024 13:40 UTC](https://discourse.nodered.org/t/change-node-can-this-be-done/85214/4 "2024-02-05T13:40:05Z")

</div>

I apologise to @Trying_to_learn if my example uses deprecated syntax. I knew that both msg.payload and payload work in jsonata, did not know one was better.

> [@E1cid](#):
>
> Compatibility mode is deprecated

Compatibility, pah! what about consistency?

It's a constant irritant in Node-red to have to write` {"payload": blah}` in one place and `{payload: blah}` in another, `msg.payload` in one place, `payload` in another and `{{payload}}` (or is it `{{msg.payload}}` ?) in a third.

What can I say about `$$.payload`? It's just pain bonkers (or do i mean jsonata?), especially on a Linux machine where `$$` is already heavily overloaded.

deep breaths... rant over.

---

<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:** [5 February 2024 13:54 UTC](https://discourse.nodered.org/t/change-node-can-this-be-done/85214/5 "2024-02-05T13:54:45Z")

</div>

> [@jbudd](#):
>
> What can I say about `$$.payload`? It's just pain bonkers

This post will give an example why $$.payload should be used.

> [@Switch node jsonata predicate match](https://discourse.nodered.org/t/switch-node-jsonata-predicate-match/82290/3):
>
> You really should tell JSOnata which scope context to look in, as in [] you are in $ scope context local loop. But payload is not in that context it is in Base scope context $$ That is why i always add the context, people think I am crazy, but if you had you would of come up with $$.roominfo.dimmers[$.device\_ieee = $$.payload.event.device\_ieee].type which would have worked straight off Notice i let JSONata know where it should be looking, even if it is not required. Looking at expressio…

> [@jbudd](#):
>
> Compatibility, pah! what about consistency?

You are using a application based on Javascript, which has no consistency, what do you expect.

---

<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:** [5 February 2024 15:10 UTC](https://discourse.nodered.org/t/change-node-can-this-be-done/85214/6 "2024-02-05T15:10:20Z")

</div>

> [@jbudd](#):
>
> `{payload: blah}`

Where do you _have_ to write it like that? In JavaScript you can use that shortcut (because there are no special characters in the property name) but it is not compulsory.

---

<div class="post-metadata">

**Author:** ![cymplecy](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/cymplecy/32/2773_2.png) [@cymplecy](https://discourse.nodered.org/u/cymplecy)\
**Post date:** [5 February 2024 16:36 UTC](https://discourse.nodered.org/t/change-node-can-this-be-done/85214/7 "2024-02-05T16:36:37Z")

</div>

It was good to get it out 🙂

---

<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:** [5 February 2024 18:39 UTC](https://discourse.nodered.org/t/change-node-can-this-be-done/85214/8 "2024-02-05T18:39:28Z")

</div>

> [@E1cid](#):
>
> You are using a application based on Javascript, which has no consistency, what do you expect.

Why did nobody warn me? Should have stuck with bash scripts...

---

<div class="post-metadata">

**Author:** ![Trying\_to\_learn](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/trying_to_learn/32/28400_2.png) [@Trying\_to\_learn](https://discourse.nodered.org/u/Trying_to_learn)\
**Post date:** [5 February 2024 20:50 UTC](https://discourse.nodered.org/t/change-node-can-this-be-done/85214/9 "2024-02-05T20:50:55Z")

</div>

Wow!

This is a can or worms.

Ok, thanks.

A **BETTER** example of where I need it is to detect if things are NOT set.

_excuse the digression_

I seem to love subflows.

As I am evolving, I am learning better (well, ok, that's from my point of view) ways to do things and using nodes more efficiently.

So I have a subflow and it has `environment` values that are used.  
In a recent example it is/was `power`

It was used in a `change` node and appended to a string.

`J: topic & '/cmnd/power' & $env('power')`

Now if power is not set in the subflow's node, I _need_ to get an error thrown or do something to set it to a default.

So my _theory_ is:

```auto
J:
power = $env('power')
if (power == undefined)
{
   throw an error
}
topic & '/cmnd/power' & $env('power')

```

I know the last line could be optimised.  
For now I'll leave it as is so as to not complicate things and keep on target for this stage.

Is/would that work - in theory?  
Or even better: really.

---

<div class="post-metadata">

**Author:** ![shrickus](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/shrickus/32/517_2.png) [@shrickus](https://discourse.nodered.org/u/shrickus)\
**Post date:** [6 February 2024 14:56 UTC](https://discourse.nodered.org/t/change-node-can-this-be-done/85214/10 "2024-02-06T14:56:40Z")

</div>

> [@E1cid](#):
>
> You are using a application based on Javascript,

... and JSONata  
... and Regex  
... and Mustache  
... and JSON  
... and Angular v1  
... and now Vuetify

So yeah, lots of different approaches with different syntaxes to handle!

Anyway, back to Andrew's dilemma -- seems you found an edge case where the JSONata expression evaluator does not validate missing env vars as well as JS does. If you want to throw an exception, you should probably use a `function` node with logic something like this:

```javascript
let power = env.get("power");
if (!power) {
  node.error("ENV 'power' is not defined!");
  return null; // stop the flow processing
}
msg.payload = msg.topic + "cmnd/power" + power;
return msg;

```

JSONata is a bit more restricted in its data types and error handling logic than JS is, because it's designed to be a JSON in =\> JSON out transformation tool, not a general purpose programming language. Incidentally, that is what makes it flexible enough to be included in node property definitions (i.e. the `change` node's `J:` option). Most of us would prefer to use plain Javascript syntax like  
`msg.topic + 'cmnd/power' + env.get('power')`

rather than the unintuitive `&` operator is JSONata -- but Javascript needs to be interpreted in a sandbox VM, and so it needs its own `function` node to provide that structure.

So if you just want to ensure a default value is used if your env var is missing, you can do this in JSONata:

```auto
(
  $power := $env("power") ? $env("power") : "MISSING";
  topic & "cmnd/power" & $power
)

```

---

<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:** [6 February 2024 15:48 UTC](https://discourse.nodered.org/t/change-node-can-this-be-done/85214/11 "2024-02-06T15:48:12Z")

</div>

To add to @shrickus, you can also call an error in the JSONata expression and stop any output, a message will be shown in the debug sidebar, but it is not catchable.  
e.g.

```auto
$$.topic & "/cmnd/" & ($env("power") ? $env("power") : $error( "ENV POWER MISSING"))

```

---

<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:** [6 May 2024 15:48 UTC](https://discourse.nodered.org/t/change-node-can-this-be-done/85214/12 "2024-05-06T15:48:24Z")

</div>

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