# Global variable in uibuilder

**URL:** <https://discourse.nodered.org/t/global-variable-in-uibuilder/29432>\
**Category:** General\
**Created:** [3 July 2020 10:44 UTC](https://discourse.nodered.org/t/global-variable-in-uibuilder/29432 "2020-07-03T10:44:45Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![YLM-UJM](https://avatars.discourse-cdn.com/v4/letter/y/9de053/32.png) [@YLM-UJM](https://discourse.nodered.org/u/YLM-UJM)\
**Post date:** [3 July 2020 10:44 UTC](https://discourse.nodered.org/t/global-variable-in-uibuilder/29432/1 "2020-07-03T10:44:45Z")

</div>

I am using the uibuilder tool which is very useful.

inside the .js file, I initialize a variable in the data object.

> var app1 = new Vue({  
> el: '#app',  
> data: {  
> startMsg : 'Vue has started, waiting for messages',  
> feVersion : '',  
> counterBtn : 0,  
> inputChkBox : false,  
> socketConnectedState : false,  
> serverTimeOffset : '[unknown]',  
> imgProps : { width: 75, height: 75 },
> 
> ```
> msgRecvd : '[Nothing]',
> msgsReceived: 0,
> msgCtrl : '[Nothing]',
> msgsControl : 0,
> 
> msgSent : '[Nothing]',
> msgsSent : 0,
> msgCtrlSent : '[Nothing]',
> msgsCtrlSent: 0,
> startAstrand: false
> }, // --- End of data --- //
> 
> ```

Then I'd like to use this varaible everywhere in my code, but it looks like it's not possible.

When I print his value inside a function inside methods it works. Then on the mounted function, I have

> uibuilder.onChange('msg', function(newVal){  
> console.log(this.startAstrand)  
> }

I got undefined. Does someone know why ?

Thanks

---

<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:** [3 July 2020 12:07 UTC](https://discourse.nodered.org/t/global-variable-in-uibuilder/29432/2 "2020-07-03T12:07:33Z")

</div>

> [@YLM-UJM](#):
>
> I got undefined. Does someone know why ?

This will be due to `this` scope & not _really_ a node-red or uibuilder question (more of a vue question) but we are helpful folk here.

So in the `mounted` function, there will be something like `var that = this` or `var myApp = this` or `var myvue = this` (I forget what it is) but - find it then instead of using `this` use `that`.

e.g.

```auto
uibuilder.onChange('msg', function(newVal){
console.log(that.startAstrand)
}

```

PS - please use the `</>` button not the `"` button for posting code 🙂

or just put code between three back ticks  
`````  
`paste code here to make it beautiful and unfettered by the forum`  
`````

---

<div class="post-metadata">

**Author:** ![afelix](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/afelix/32/9743_2.png) [@afelix](https://discourse.nodered.org/u/afelix)\
**Post date:** [3 July 2020 13:13 UTC](https://discourse.nodered.org/t/global-variable-in-uibuilder/29432/3 "2020-07-03T13:13:21Z")

</div>

> [@Steve-Mcl](#):
>
> This will be due to `this` scope & not _really_ a node-red or uibuilder question (more of a vue question) but we are helpful folk here.

To further explain it, this is a JavaScript thing, and since Vue and most things that you'd use on Uibuilder have javascript inside, it's definitely relevant. You might also run into this if you're doing complex stuff in function nodes, so it is relevant for the forums in more reason than one 🙂

In JavaScript, `this` points to the scope of the current function you're in. Say that you have a structure that looks like this (pseudocode for showing):

```auto
// code before A
function A(...) {
   // inside A
}
// code after A

```

Anything you define to `this` inside A, is only available within that function.  
However, it gets complicated when you have functions within functions, like in the `mounted` function of a Vue app in Uibuilder:

```auto
// before function (position 1)
mounted: function (...) {
    // inside function mounted (position 2)
    uibuilder.onChange('msg', function(newValue) {
        // in onChange function (position 3)
    }
    // inside function mounted (position 4)
}
// after function mounted (position 5)

```

When you're at position 2, `this.startAstrand` refers to the variable `startAstrand` that you put in your `data` structure. On posiition 3 however, `this` has changed to become local in the `onChange` function, and holds no longer a reference to the data structure. You can get around that by defining a variable for yourself inside the outer function mounted, with a name that sounds logical for you, for example `that` or `vueApp` (which I think is what Julian defaults to in the examples), and assign it the value of `this`, because at position 2 `this` still points to the right values. As the variable defined in position 2 will have a wide enough scope to be reachable at positions 3 and even 4, you can then use your `that.startAstrand` or `vueApp.startAstrand` or whatever you created in position 3. In position 4 you can choose whether you'd like to use `this.startAstrand` again, or go with the earlier created `that.startAstrand` or similar.

It's a bit abstract, but I hope that helps.

---

<div class="post-metadata">

**Author:** ![YLM-UJM](https://avatars.discourse-cdn.com/v4/letter/y/9de053/32.png) [@YLM-UJM](https://discourse.nodered.org/u/YLM-UJM)\
**Post date:** [3 July 2020 13:41 UTC](https://discourse.nodered.org/t/global-variable-in-uibuilder/29432/4 "2020-07-03T13:41:02Z")

</div>

Thank you to both of you, those explanations were very useful, I learnt something and it works perfectly !!

---

<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:** [4 July 2020 12:44 UTC](https://discourse.nodered.org/t/global-variable-in-uibuilder/29432/5 "2020-07-04T12:44:22Z")

</div>

Just to note that the template .js file already has `this` assigned to a variable - `vueApp` inside the `mounted` function for that very reason.

In fact though, you don't really need to do that since I already assign the new vue instance to `app1` right at the start. So both `app1` and `vueApp` are pretty much the same thing.

But certainly, the bottom line in JS (and probably in all languages that implement `this`) is that if you have sub-functions/methods defined inside another function or class, it is always safer to take a reference to `this`.

Because JavaScript mostly assigns "references" rather than "copies" when you assign one thing to another, you don't generally have to worry about assignments making your code bloated. (strictly speaking, JS does a copy if the thing on the right hand side of the equals sign is a "[primitive](https://developer.mozilla.org/en-US/docs/Glossary/Primitive)" data type such as a number, string, boolean, etc. For everything else, I believe it just creates a reference - a "link" if you like.)

---

<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:** [2 September 2020 12:44 UTC](https://discourse.nodered.org/t/global-variable-in-uibuilder/29432/6 "2020-09-02T12:44:22Z")

</div>

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