# Function node & var definition

**URL:** <https://discourse.nodered.org/t/function-node-var-definition/71492>\
**Category:** General\
**Tags:** function-node\
**Created:** [30 November 2022 08:17 UTC](https://discourse.nodered.org/t/function-node-var-definition/71492 "2022-11-30T08:17:27Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![pacmanmt](https://avatars.discourse-cdn.com/v4/letter/p/dfb087/32.png) [@pacmanmt](https://discourse.nodered.org/u/pacmanmt)\
**Post date:** [30 November 2022 08:17 UTC](https://discourse.nodered.org/t/function-node-var-definition/71492/1 "2022-11-30T08:17:27Z")

</div>

I must anticipate that I am not a programmer and most comes from cut & paste from others work.  
I cannot understand the behavior of a function node I am using (NodeRed 3.0.2 and Monaco editor).  
The function uses a Case statement:

```auto
var data = msg.payload.split("\t");
switch (data[0]) {
    case 'SOC':
        stateoc = parseFloat(data[1] / 10);
        break;
    case 'V':
        voltag = parseFloat(data[1] / 1000);
        break;
    case 'I':
        curren = parseFloat(data[1] / 1000);
        break;
}
return [
    {
        payload: {
            SOC: stateoc,
            Voltage: voltag,
            Current: curren
        }
    }
]

```

but written like this I get: "ReferenceError: 'name' is not defined (line 16, col 18)" for the three variables used. If I run the flow, after the error messages, the function works fine.  
If I resolve the error message defining the variables with var or let (same result for both), I get no error but the function doesn't work anymore and all the variables results are undefined.  
Any clue on this behavior?

---

<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:** [30 November 2022 09:44 UTC](https://discourse.nodered.org/t/function-node-var-definition/71492/2 "2022-11-30T09:44:47Z")

</div>

For the variables inside the switch statement, if you use `let` or `const` to define them, the JavaScript standard ensures that they exist only within the current context. In your case, the context is within the individual case statement.

If you use the older `var` to define them, they are "hoisted" to the top of the function internally so that will work. Using them without a definition will make them global. In the case of a node-red function node, that doesn't mean much because each function node operates in a node.js virtual environment. However, both of these approaches are very much discouraged since in other contexts, they can cause various issues.

The thing to do here would be to define the variables at the top of the function:

```auto
const data = msg.payload.split("\t");
let stateoc, voltag, curren // defines the vars but does not give them a value
switch (data[0]) {
    case 'SOC': {
        stateoc = parseFloat(data[1] / 10);
        break;
    }
    case 'V': {
        voltag = parseFloat(data[1] / 1000);
        break;
    }
    case 'I': {
        curren = parseFloat(data[1] / 1000);
        break;
   }
   default: { // always good practice to define this even if you don't use it
       // nothing to do? or do you want an error shown?
   }
}
return [
    {
        payload: {
            SOC: stateoc,
            Voltage: voltag,
            Current: curren
        }
    }
]

```

Note that I've also wrapped the `case` code blocks in `{ ... }` which makes things a lot clearer (to me anyway) and there are a couple of rare edge-cases that are avoided.

---

<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:** [30 November 2022 09:45 UTC](https://discourse.nodered.org/t/function-node-var-definition/71492/3 "2022-11-30T09:45:55Z")

</div>

Just guessing (as not near a computer) but I suspect you need to change the definition of 'msg' to an object.

```auto
var data = msg.payload.split("\t");
switch (data[0]) {
    case 'SOC':
        stateoc = parseFloat(data[1] / 10);
        break;
    case 'V':
        voltag = parseFloat(data[1] / 1000);
        break;
    case 'I':
        curren = parseFloat(data[1] / 1000);
        break;
}

msg.payload = {}; // <<<<<<<<<<<< Try adding this line and see if it works ??
return [
    {
        payload: {
            SOC: stateoc,
            Voltage: voltag,
            Current: curren
        }
    }
]

```

---

<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:** [30 November 2022 10:04 UTC](https://discourse.nodered.org/t/function-node-var-definition/71492/4 "2022-11-30T10:04:38Z")

</div>

You have another problem, in that each time through only one of stateoc, voltag and curren will be calculated. So in the return statement, where you setup the payload, the other two will be set to undefined.

It doesn't cause an error, but you don't need the square brackets around the return message, since there is only one. Finally it is generally better practice to modify the original message and send that back, rather than create a new message. So the last part would read

```auto
msg.payload = {
            SOC: stateoc,
            Voltage: voltag,
            Current: curren
}
return msg

```

---

<div class="post-metadata">

**Author:** ![pacmanmt](https://avatars.discourse-cdn.com/v4/letter/p/dfb087/32.png) [@pacmanmt](https://discourse.nodered.org/u/pacmanmt)\
**Post date:** [30 November 2022 10:34 UTC](https://discourse.nodered.org/t/function-node-var-definition/71492/5 "2022-11-30T10:34:50Z")

</div>

> [@TotallyInformation](#):
>
> `let stateoc, voltag, curren`

Thank you so much, I tried your suggestion, but as with my previous attempts, if I declare the variables with "let" the functions return undefined values; if I remove the variables declaration, i get the initial error but then the function works with the expected results

---

<div class="post-metadata">

**Author:** ![pacmanmt](https://avatars.discourse-cdn.com/v4/letter/p/dfb087/32.png) [@pacmanmt](https://discourse.nodered.org/u/pacmanmt)\
**Post date:** [30 November 2022 10:36 UTC](https://discourse.nodered.org/t/function-node-var-definition/71492/6 "2022-11-30T10:36:07Z")

</div>

Tried even this one, but it changes nothing. Thanks anyway

---

<div class="post-metadata">

**Author:** ![pacmanmt](https://avatars.discourse-cdn.com/v4/letter/p/dfb087/32.png) [@pacmanmt](https://discourse.nodered.org/u/pacmanmt)\
**Post date:** [30 November 2022 10:37 UTC](https://discourse.nodered.org/t/function-node-var-definition/71492/7 "2022-11-30T10:37:46Z")

</div>

Thanks Colin, you are right but in this way every now and then I get a payload at "0" that I don't get in the other way.

---

<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:** [30 November 2022 10:47 UTC](https://discourse.nodered.org/t/function-node-var-definition/71492/8 "2022-11-30T10:47:19Z")

</div>

The change I suggested would not cause zeros. To check, have two functions, your original and the modified one, and connect them both to the same source. Check the outputs of both to see if they are different.

---

<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:** [30 November 2022 11:31 UTC](https://discourse.nodered.org/t/function-node-var-definition/71492/9 "2022-11-30T11:31:03Z")

</div>

> [@pacmanmt](#):
>
> Thank you so much, I tried your suggestion, but as with my previous attempts, if I declare the variables with "let" the functions return undefined values; if I remove the variables declaration, i get the initial error but then the function works with the expected results

Can you please share your updated code.

---

<div class="post-metadata">

**Author:** ![pacmanmt](https://avatars.discourse-cdn.com/v4/letter/p/dfb087/32.png) [@pacmanmt](https://discourse.nodered.org/u/pacmanmt)\
**Post date:** [30 November 2022 12:03 UTC](https://discourse.nodered.org/t/function-node-var-definition/71492/10 "2022-11-30T12:03:09Z")

</div>

Yes they are, mine has no zeros. 🤔

---

<div class="post-metadata">

**Author:** ![pacmanmt](https://avatars.discourse-cdn.com/v4/letter/p/dfb087/32.png) [@pacmanmt](https://discourse.nodered.org/u/pacmanmt)\
**Post date:** [30 November 2022 12:03 UTC](https://discourse.nodered.org/t/function-node-var-definition/71492/11 "2022-11-30T12:03:46Z")

</div>

I just copied and pasted your code

---

<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:** [30 November 2022 12:04 UTC](https://discourse.nodered.org/t/function-node-var-definition/71492/12 "2022-11-30T12:04:36Z")

</div>

Please post the function you are now using. How can you have copied @TotallyInformation's code if you have my changes in too?

---

<div class="post-metadata">

**Author:** ![pacmanmt](https://avatars.discourse-cdn.com/v4/letter/p/dfb087/32.png) [@pacmanmt](https://discourse.nodered.org/u/pacmanmt)\
**Post date:** [30 November 2022 12:09 UTC](https://discourse.nodered.org/t/function-node-var-definition/71492/13 "2022-11-30T12:09:42Z")

</div>

I have tried every single suggestion by itself and checked the result, then answered to each of you regarding his suggested change.

---

<div class="post-metadata">

**Author:** ![pacmanmt](https://avatars.discourse-cdn.com/v4/letter/p/dfb087/32.png) [@pacmanmt](https://discourse.nodered.org/u/pacmanmt)\
**Post date:** [30 November 2022 12:15 UTC](https://discourse.nodered.org/t/function-node-var-definition/71492/14 "2022-11-30T12:15:57Z")

</div>

> [@Colin](#):
>
> ```auto
> msg.payload = {
> SOC: stateoc,
> Voltage: voltag,
> Current: curren
> }
> return msg
> 
> ```

Anyway this is the code with both suggestions:

```auto
const data = msg.payload.split("\t");
let stateoc, voltag, curren;
switch (data[0]) {
    case 'SOC':
        stateoc = parseFloat(data[1] / 10);
        break;
    case 'V':
        voltag = parseFloat(data[1] / 1000);
        break;
    case 'I':
        curren = parseFloat(data[1] / 1000);
        break;
}
msg.payload = {
    SOC: stateoc,
    Voltage: voltag,
    Current: curren
}
return msg;

```

and this is the debug output running this code:  
 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/2/8/28a6eadf8063a68db9a3c7a87de345cac348590c.png)

---

<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:** [30 November 2022 12:18 UTC](https://discourse.nodered.org/t/function-node-var-definition/71492/15 "2022-11-30T12:18:26Z")

</div>

And a debug of the message going in?

\*\*[Edit]\*\*Also add a line after the split

```auto
node.warn(`data[0]: ${data[0]}`)

```

---

<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:** [30 November 2022 12:31 UTC](https://discourse.nodered.org/t/function-node-var-definition/71492/16 "2022-11-30T12:31:24Z")

</div>

> [@pacmanmt](#):
>
> Anyway this is the code with both suggestions

Not quite what I posted. At the least, you need to add a test to make sure that you handle the case where `data` is not an array (because there was nothing to split - e.g. no tab in the text), you should also use try/catch around the first line in case the split fails completely. You also need to include my suggestion of handling the case where `data[0]` is not one of your specified values. That's what the `default` case does.

---

<div class="post-metadata">

**Author:** ![pacmanmt](https://avatars.discourse-cdn.com/v4/letter/p/dfb087/32.png) [@pacmanmt](https://discourse.nodered.org/u/pacmanmt)\
**Post date:** [30 November 2022 12:59 UTC](https://discourse.nodered.org/t/function-node-var-definition/71492/17 "2022-11-30T12:59:33Z")

</div>

> [@Colin](#):
>
> `node.warn(`data[0]: ${data[0]}`)`

The incoming message is always the same, already checked with a debug node.  
In any case the point is that, leaving the input untouched, the function has the reference error but gives the right outcome if I do not declare the variables and gives the undefined values if I declare the variables. All the other staying the same.

---

<div class="post-metadata">

**Author:** ![pacmanmt](https://avatars.discourse-cdn.com/v4/letter/p/dfb087/32.png) [@pacmanmt](https://discourse.nodered.org/u/pacmanmt)\
**Post date:** [30 November 2022 13:03 UTC](https://discourse.nodered.org/t/function-node-var-definition/71492/18 "2022-11-30T13:03:48Z")

</div>

You are right, but even using your code exactly as you have written, the results are the ones I have already put in my answer.  
All the cosmetics of good programming have not changed the results as just replied to Colin.

Just for the sake of completeness the incoming messages are from a serial port node of a Victron BMV 712, the format is factory defined with tabs separating labels from values. I checked for hours and the incoming messages are always formatted in the same way.

---

<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:** [30 November 2022 13:45 UTC](https://discourse.nodered.org/t/function-node-var-definition/71492/19 "2022-11-30T13:45:40Z")

</div>

Please do as we ask. Add the warn and the debug node before and after and show us what you see. Perhaps you are just missing something. Why do you resist doing what we ask?

---

<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:** [30 November 2022 14:54 UTC](https://discourse.nodered.org/t/function-node-var-definition/71492/20 "2022-11-30T14:54:38Z")

</div>

and at least share an input msg that fails and one that works so that we can help. Without that info, we can't help, especially if you don't put the other checks into your code.

[Next page](https://discourse.nodered.org/t/function-node-var-definition/71492.md?page=2)
