Difference in load() with () and other functions

A Score Level 1

Hi folks,

Can anyone please tell me the difference between load(),with(), a!localvariable and a!refreshvariable functions. In what different scenarios are all these used. Is a!localvariable replacement of load and with both ?

It would be better if someone explain them using a code snippet.

  Discussion posts and replies are publicly visible

  • 0
    A Score Level 1
    in reply to juergeng393

    This doesnt' have any info on a!localvariable function . I need to find difference between load and a!localvariable function.

  • interesting position...I'd be interested in how you'd implement a nested a!forEach() where the inner loop requires a value from each outer loop. Obviously one option would be to write a rule that passed the entire fv!item, from which you'd extract the outer value and all the inner values...but if you wanted to do this without such a helper rule, you could use a with() to define a local!variable that you could set (and re-set) for each outer loop and that is now made available to the inner loop.

  • 0
    Certified Lead Developer
    in reply to Stewart Burchell

    Wait, are you saying that couldn't be done with a!localVariables()?  Why?

  • 0
    Certified Lead Developer

    load():  Variables in here only evaluated once when the form first loads.  By "evaluated" we mean run the code that comes after the variable definition.  Since the code is only ever run once, it means we can save values in these local variables that won't immediately get overwritten.  So you're actually required to use load() to make a variable that can be saved to.

    with():  Variables in here get reevaluated absolutely every time the user does anything with the form at all.  This allows for dynamic content, or things that refresh on a button click, for instance.  You don't even need to configure the button to really do anything.  It just causes the with variables to be reevaluated.  If you define an empty with() variable, it gets re-emptied every time the user clicks or types anything, so nothing can be saved there.

    a!localVariables() fully replaces load and with.  The reason load and with aren't relics yet is because essentially every application ever uses only those.  But load() and with() are now essentially tech debt, but tech debt that EVERYONE still has, pretty much.

    Each of your variables inside a!localVariables() should be defined with it's own a!refreshVariable function.  That function takes 2 parameters, where you define what the variable is, and define when that gets reevaluated.  Now you have not only the option of "never" and "any time the user does anything", but also things like "every 30 seconds" or "when this variable changes" or "when some other variable changes".  You should use this, because now you only have to make your with() variables update when it MATTERS whether they update or not.  But you can only do that by porting them over to a!localVariables and defining them with the proper a!refreshVariable.

  • 0
    Certified Lead Developer
    in reply to Dave Lewis
    Each of your variables inside a!localVariables() should be defined with it's own a!refreshVariable function.

    I would differ on this point.  Local variables can also be defined simply with the value instead of the a!refreshVariable function, as long as the default functionality of a refresh variable is fine.  This includes refreshing on referenced variable change, NOT refreshing always, and not doing any of the more advanced refreshes.  I'd estimate that for maybe 80 - 90% of your average local variable use cases, this default setting will either be OK or will just make no difference, and for the remaining ones, you'd use a!refreshVariable().

  • Because you can't assign a value to a local!variable from within the scope of the a!forEach() - or, if you can, I'm not seeing how that's done. Here's what I've just experimented with. First is what works using a with():

    a!localVariables(
      local!myNestedArray: {
        {
          {record: 1, attributes: {"A","B","C"}},
          {record: 2, attributes: {"D","E","F"}}
        },
      },
      a!forEach(
        items: local!myNestedArray,
        expression: with(
          local!currentItem: concat("SJB/", fv!item.record),
          a!forEach(
            items: fv!item.attributes,
            expression: {
              local!currentItem,
              fv!item
            }
          )
        )
      )
    )

    ...and secondly here's what I've tried to do just using local!variables (which I can't get to work):

    a!localVariables(
      local!myNestedArray: {
        {
          {record: 1, attributes: {"A","B","C"}},
          {record: 2, attributes: {"D","E","F"}}
        },
      },
      local!currentItem: null,
      a!forEach(
        items: local!myNestedArray,
        expression: {
          local!currentItem: fv!item.record,
          a!forEach(
            items: fv!item.attributes,
            expression: {
              local!currentItem,
              fv!item
            }
          )
        }
      )
    )

    Arguably (and I might take that position for more a more sophisticated transformation in the inner loop) you'd have a helper rule. And maybe that's best practice, but I'm always (!) suspicious when someone is definitive in their reply! ;-)

  • 0
    Certified Lead Developer
    in reply to Stewart Burchell

    Found your problem... you replaced with(), with nothing, instead of a!localVariables()...

    should be:

    a!localVariables(
      local!myNestedArray: {
        {
          {record: 1, attributes: {"A","B","C"}},
          {record: 2, attributes: {"D","E","F"}}
        },
      },
      local!currentItem: null,
      a!forEach(
        items: local!myNestedArray,
        expression: a!localVariables(
          local!currentItem: fv!item.record,
          a!forEach(
            items: fv!item.attributes,
            expression: {
              local!currentItem,
              fv!item
            }
          )
        )
      )
    )

  • 0
    Certified Lead Developer
    in reply to Mike Schmitt

    Nice catch!

    It is really nice that they made the default so useful.  Now you can easily do things like run a queryEntity with a different parameter but only when the parameter actually changes.

    And I suppose if it doesn't reference any other variables, it's just a load() at that point, right?