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

  • 0
    Certified Lead Developer

    Can you post your code using following instead of the image.

  • 0
    Certified Lead Developer

    It's simple. The variable is accessible within the block into which it is defined.

    See the following to understand it better -

    a!localVariables(
      local!a: 1,
      {
        a!localVariables(local!b: 2, local!a),
        local!b
      }
    )

  • Abhay,

    Here is the code - emblem

    a!localVariables(
      local!selection,
      local!selectedEmployees,
      local!showIneligible:true,
      {
        a!checkboxField(
          label: "Checkboxes",
          labelPosition: "COLLAPSED",
          choiceLabels: {"Show ineligible employees"},
          choiceValues: {true()},
          value: if(local!showIneligible, true(),null()),
          saveInto: a!save(
            local!showIneligible,
            if(
              isnull(save!value),
              false(),
              true()
            )
          ),
          validations: {}
        ),
      a!columnsLayout(
        columns: {
          a!columnLayout(
            contents: {
              a!gridField(
                label: "Employee Directory",
                labelPosition: "ABOVE",
                data: a!queryEntity(
                  entity: cons!CR_EMPLOYEE_ENTY_CNST,
                  query: a!query(
                    selection: a!querySelection(
                      columns: {
                        a!queryColumn(
                          field: "id"
                        ),
                        a!queryColumn(
                          field: "firstName"
                        ),
                        a!queryColumn(
                          field: "lastName"
                        ),
                        a!queryColumn(
                          field: "department"
                        ),
                        a!queryColumn(
                          field: "startDate"
                        )
                      }
                    ),
                    logicalExpression: a!queryLogicalExpression(
                      operator: "AND",
                      filters: {
                        a!queryFilter(
                          field: "department",
                          operator: "<>",
                          value: "Sales",
                          applyWhen: not(local!showIneligible)
                        )
                      },
                      ignoreFiltersWithEmptyValues: true
                    ),
                    pagingInfo: fv!pagingInfo
                  ),
                  fetchTotalCount: true
                ),
                columns: {
                  a!gridColumn(
                    label: "First Name",
                    sortField: "firstName",
                    value: fv!row.firstName,
                    showWhen:a!isNotNullOrEmpty(fv!row.firstName)
                  ),
                  a!gridColumn(
                    label: "Last Name",
                    sortField: "lastName",
                    value: fv!row.lastName
                    /*showWhen:a!isNotNullOrEmpty(fv!row.lastName)*/
                  ),
                  a!gridColumn(
                    label: "Department",
                    sortField: "department",
                    value: a!richTextDisplayField(
                      value: {
                        a!richTextItem(
                          text: {fv!row.department},
                          color: if(fv!row.department="Sales","SECONDARY",null),
                          style: {
                            "EMPHASIS"
                          }
                        )
                      }
                    )
                  ),
                  a!gridColumn(
                    label: "Start Date",
                    sortField: "startDate",
                    value: if(
                    isnull(fv!row.startDate),
                    fv!row.startDate,
                    datetext(fv!row.startDate, "default")
                    ),
                    align: "END"
                  ),
                  a!gridColumn(
                    label: "Id",
                    sortField: "id",
                    value: fv!row.id,
                    align: "END"
                  )
                },
                initialSorts: {
                  a!sortInfo(
                    field: "lastName",
                    ascending: true
                  )
                },
                selectable: true,
                selectionValue: local!selection,
                selectionSaveInto: {
                  local!selection,
    
                  /* This save adds the full rows of data for items selected in the most recent user interaction to local!selectedEmployees. */
                  a!save(local!selectedEmployees, append(local!selectedEmployees,fv!selectedRows)),
                  /* This save removes the full rows of data for items deselected in the most recent user interaction to local!selectedEmployees */
                  a!save(local!selectedEmployees, difference(local!selectedEmployees,fv!deselectedRows))
                },
                disableRowSelectionWhen: fv!row.department="Sales",
                validations: {}
              )
            },
            width: "WIDE"
          ),
          a!columnLayout(
            contents: {
              a!richTextDisplayField(
                label: "Selected Employees",
                labelPosition: "ABOVE",
                value: a!forEach(
                  items:local!selectedEmployees,
                  expression: {
                    a!richTextIcon(
                      icon:"user-circle"
                    ),
                    " " & fv!item.firstName & " " & fv!item.lastName & char(10)
                  }
                )
              )
            }
          )
        }
      )
    }
    )

  • Abhay,

    That was understanding - variable is available within the defined block.  Unless, I am missing something, I don't see why line 8 in my example (second image in my original post) gives an error when the variable is defined on line 3.  However, if I remove the braces on line 2 and 24, the error goes away (see image below).

    Madhu

  • 0
    Certified Lead Developer
    in reply to MaNa

    looks like fv!raw can only be used in the value parameter. Remove it from showWhen:a!isNotNullOrEmpty(fv!row.firstName)

    Instead do following.

    1. Define local variable (e.g. local!data) and capture the query result set into it.

    2. Refer local!data into gridField -> data.

    3. For showWhen condition Use local!data.firstName = <something>

  • 0
    Certified Lead Developer
    in reply to MaNa

    Please try to understand the syntax of a!localVariables().

    a!localVariableslocalVar1, localVarN, expression )

    In your image2, you have defined local!productsList without using localVariable() which is violating the syntax because it is the expression portion.

    use something like following.

    a!localVariables(
      {
        a!localVariables(
          local!productList: rule!abc(),
          a!gridField()
        )
      }
    )

    See the color coding to understand it better.

  • 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.