Set value - Name and Global Name values discussion

Since day one of using Wappler I confess to being a little unsure of how the server connect Set value component works in relation to names and global names and could not find clarification within forum docs so today I have investigated and these are my conclusions.

So here is my take on this and my questions about them

We start with

image

At this point I have always assumed that the difference between the Name and the Global Name were about scope, Name being of local scope, Global being just that, a global variable

So I define a variable in a Set Value stage like this

image

From this I assume I have defined a local scope variable test which has also global scope when referenced as GtestVar

So now I define a second variable

image

GtestVar, the global name does not appear in the data picker so has to be referenced by manually entering the name

So variable test, Global Name GtestVar was 6 so tmp will inherit that value of 6 (and it does).

At this time we are still in the same scope so tmp and GtestVar are effectively the same thing

now I add a database query and a repeat

image

This effectively creates a new name space
so i again add a variable names tmp and assign a value of 5

Now we have two definitions of tmp, the initial definition giving a value of 6 and another within a different scope with the value 5. within the loop the original tmp is in the parent namespace so must be reference as $parent.tmp or it’s global name {{GtestVar}}

(don’t worry if you are getting confused at this point, all will become clear by the end)

So to prove the referencing I now I define an additional variable tmp2 and set it’s value to $parent.test which should be 6

image

(So if we can reference the parent this way why bother with global names? Simple, with complex actions we could end up with situations like $parent.$parent.$parent.$parent.test. Globals make this so much easier and ensure the correct instance is selected.)

We now define another variable test with value {{GtestVar}}

image

So now we have a variable at top level

test, global name GtestVar = 6
tmp = GtestVar = 6

in a “lower” namespace we have
tmp = 5
tmp2 = $parent.tmp which should be 6
test = {{GtestVar}} = 6

So i run the query and here is the output as expected with two variables called tmp with different values depending on how they are referenced

image

So to summarise we can see that those set within the repeat scope assume the values of those in the main parent scope by reference to the Global name or $parent reference however where identical name references occur in different scopes as in “tmp” each instance has its own unique value

If I am correct this is extremely important to understand when dealing with nested actions within Server action or incorrect values may be used due to multiple instances of identically names variables

Have I understood this correctly?
Have I explained this in a way you understand?

12 Likes

How would you do the opposite ?
Meaning set a global variable value from a local scope ?
Thanks !

Wow, Brian, I’m just coming up against understanding this, and I hadn’t even thought of all the things you have enlightened me with!

So your discussion covers the idea of a variable being “global” within different name spaces in the same server action file.

I’m interested in whether a variable can be global across different server action files which are all called from the same index.php, without the variable needing to be a session variable.

Did anyone test that one out?

In the same boat as you with this Brian, and this has certainly clarified things a little, although I have to admit I have often found the using more than one $parent seems to stop it working. So $parent.$parent.test seems to not work well in my testing.

If i want “global” variables throughout multiple server actions I always use server sessions, that’s what they are there for after all

Quick question Brian @Hyperbytes, have you found a way to change a local or global variable value later on.
In other words I set value of test as 1 and then 10 other actions run and i want to change the value of test to 2, so not creating a new variable in another scope but actually change the value of the original variable after certain conditions have been met?

Gut feeling is the “local scope” variable is destroyed when namespace of that scope closes. Globals should be re-definable at any time within the root namespace. I guess the trick is not to use the same name for the local and global definitions so they are independent. personally i am old fashioned and tend to use sessions for anything global, always have, probably always will

1 Like

I’ve got a question on this… is there any reason not to make the global name the same as the local name?
It saves having to think about whether it is in scope or not, and keeps things the same if you move the scope of a statement!

Then how could you be certain you were referencing the correct instance of the variable if you have 2 different with the same name?

I always set the Name and Global Name to be the same every time I use the Set Value action. It’s just a habit I got into at the start. I’ve never really understood why we set both and what the benefit it. For me, I just want a variable to be available throughout the action file.

If I want two variables to be independent in different scopes then I simply give them different names but always having the Name and Global Name the same.

I’m pretty sure I’m missing out on something because of my lack of using parents so would welcome why I should change my current method of working.

Hi Jon

Basically, if you define a set value with a name of myvar and a global name of g_myvar

myvar is limited to the the scope it resides so, for example, inside a repeat it only exists in that repeat and is discarded at the end of that scope.
the global g_myvar will continue to exist and will have a value at all times during the API action. The global effectively acts as a temporary, API long session

3 Likes

Thanks Brian. That was my understanding so I’m glad I’ve understood it correctly. However, what is the benefit of having it only existing within a repeat and not across the whole API session? That’s the bit I’m unclear of the benefit. I don’t mind if a variable keeps its value the whole time. I just won’t reference it if I don’t need it.

Keeping a variable available for the local scope only is mainly for avoiding name collisions, preventing it from interfering with other parts of the script, better readability, easier for debugging, memory efficiency.
Still this depends on your user case :slight_smile:

2 Likes

As the value can change with each iteration, it allows you to track changes.
Second reason is Wappler does not allow a set value without a local scope name so you have to set both!

3 Likes

Loving the debate! :sunny:

Hm… I also did this, until something broke and Patrick said it was working as intended :grimacing:

If I’m not mistaken, the non-global variable has priority over the global one when under the same scope, and this made the logic I saw different from what I predicted. Sorry I don’t recall the situation in specific, but I opened a bug report, which was probably moved to the How To category for not being a bug.

Since then, I always suffix global variables with _g

4 Likes

That’s helpful info @Apple.

But if I always set the Name and Global Name the same (eg. var1) then it will always update both so would always be predictable, won’t it? I can only see problems happening if the same var name is set when the Global Name is left blank or uses a different name to the Name part.

Is that right?

If you do a Set Value inside a Repeat step, you’re dealing with two scopes: the parent scope, and the scope of the Repeat. You’re using the same variable names, yet affecting the scopes differently. The parent scope will have a different global variable than the local, because you modified inside the Repeat, so you now have two variables with the same name but with different content

I think that’s the issue I observed

So putting {{var1}} inside a repeat somewhere would produce a different value than the same {{var1}} put in a different repeat even if every time I did a Set Value I put var1 in both Name and Global Name?

Surely if I use a Set Value anywhere and put var1 in both Name and Global Name then this new value will be returned when I put {{var1}} somewhere regardless of where it is?

Jon, I think you make the very case for non naming them the same

On local scope {{var1}} in the repeat is indeed different to {{var1}} in another repear as they are both local to the level of the containing repeat.
Global {{var1}} would be the last value ANY of the {{var1}} local scopes I guess
But, as Apple suggests, local scope is reported when global and local names are the same within the same repeat so the results could be confusing.

So going back to what i said, i see no benefit and some disadvantages of naming the scopes the same so why would you?

1 Like