Trying to understand local/scoping of variables

Hi:

I was experimenting with the Grid example in Appian Tutorials (https://docs.appian.com/suite/help/23.1/Grid_Tutorial.html) and noticed that I had some rows with no firstName and LastName.  So, I thought I would use "fv!row.firstName" as part of the showWhen-attribute to prevent those rows from being show (see image below).  However, I am getting "scoping error" messages.  I know I can use query to filter out those rows but thought I would experiment with this approach because I have had issues with understanding local-variable scoping.  For example, when I use {} right after a!localVariables (), I get scoping error (see second image. 

Any responses to helping me understand local-variables/scoping would be appreciated.

Thank you.

Ma

  Discussion posts and replies are publicly visible

Parents Reply Children
  • Abhay:

    Thanks for helping me understand this concept.  As for the syntax in image 2, isn't the a!localVariable() on line 1, similar to the example in your response?

    Isn't the scope defined by a!localVariable valid for all statements between matching pairs of ()?  So anything you defined after line 1 should be available throughout the rest of the code.  Am I wrong in that interpretation ?

    I was using this as the reference (https://docs.appian.com/suite/help/23.1/Local_Variables.html).  In the example they have:

    value: if(isnull(local!input), "No", "Yes"),

    While I understand I am using "fv!row" not "local!input" as part of showWhen attribute (showWhen:a!isNotNullOrEmpty(fv!row.number)) , it gives me an error (image 1 in original post).  I am trying to understand why/when I can use "fv!row" and why there is a scoping error.

    a!columnsLayout(
      columns: {
        a!localVariables(
          local!input,
          {
            a!columnLayout(
              contents: {
                a!textField(
                  label: "Input",
                  value: local!input,
                  saveInto: local!input
                )
              }
            ),
            a!columnLayout(
              contents: {
                a!textField(
                  label: "Input Entered?",
                  value: if(isnull(local!input), "No", "Yes"),
                  readOnly: true
                )
              }
            )
          }
        )
      }
    )
    

  • 0
    Certified Lead Developer
    in reply to MaNa

    It is not the same. Because of the added curly brackets that local variable is never declared as Appian evaluates this as the expression part of a!localVariables.

  • Stefan,

    I can accept that Appian treats the curly-braces as the start of an expression.  Back to my original issue, which is why is using "fv!row" (image below) causing a scoping variable issue.  Isn't fv!row part of the gridField function that should be available at line:56?  It is available at line 55.  If passing it to the isNotNullorEmpty function is the issue, how do I access the value of fv!row in a function/expression for something like let's say to determine if the row is an odd or even row?

    Thanks for your help.

  • 0
    Certified Lead Developer
    in reply to MaNa

    So, facts first. As per the documentation fv!row can ONLY be used when assigning to the value parameter.

    https://docs.appian.com/suite/help/23.1/Grid_Column_Component.html#parameters

    Now, about the why. It just does not make sense in any other parameter as the gridColumn component defines the logic for the whole column.

    If you want to show/hide a component in an individual cell, just add a richttextdisplayfield and make it show data according to your logic.

  • I guess what I am looking for is something similar to 'disableRowSelectionWhen' that would allow me to hide an entire row if one or more columns have is empty/null.

  • 0
    Certified Lead Developer
    in reply to MaNa
    that would allow me to hide an entire row if one or more columns have is empty/null

    You might want to think a bit more about this.  Why would you want to hide a row when a column has an entirely empty/null value?  What would this even look like / accomplish?

  • Mike,

    The use case is when multiple faculty members submit grades for a student and GPAs are calculated after all faculty members submit their grades.  Until all grades are submitted, the GPA column is null.  So, I didn't want the interface displaying any rows where GPA column is null.

    Guess the right approach would be to filter the data (pass only rows where the GPA column is not NULL) but I was experimenting to explore if there was a way to provide users with an option to either view or not view a row based on a column value (e.g., show only students/GPAs that qualify for Deans' List).

  • 0
    Certified Lead Developer
    in reply to MaNa

    I support you idea of fetching only the required data instead of fetching all, wasting memory and trying to hide some of the data in the UI.

  • 0
    Certified Lead Developer
    in reply to MaNa

    Yes, if the requirement is that your form should show GPA and that the only rows which appear are those where it's non-blank, then the key is to filter your data in advance of feeding it into your grid.

    If you're querying the data from the DB, then you would simply provide a query filter and filter out rows where that value is not populated.

    If, on the other hand, you are passing the whole data set (with a mixture of rows) like as a process PV array, then you could instead create an on-form temp variable consisting only of the rows you'd like to display.  Something along the lines of, local!myTempArray: a!forEach(ri!myWholeArray, if(a!isNullOrEmpty(fv!item.GPA), {}, fv!item) within your local variables declaration.  Then you'd simply pass that local variable into the data parameter of your grid, and you'd be displaying only the rows which have a value populated here.

  • 0
    Certified Lead Developer
    in reply to MaNa
    As for the syntax in image 2, isn't the a!localVariable() on line 1, similar to the example in your response?

    No it is not. The {} start the expression part and you cannot define local variable in the expression part directly the way you did it. To do that you need to have another nested localvariable() function, as I mentioned in my previous response. Hope this helps!