Problem in "Interfaces Tutorial 103"... with a type

hi,

I have a littel problem with the online Course  "Interfaces 103: Build Dynamic Interfaces", "Part3 : Creating an editable grid" at "54 sec" in the video.

The tutor shows at this point how to add a row to the editable grid by using the addRowLink property and a a!dynamicLink() function in conjunction with a!saveInto() function.
He then saves into his rule input ri!Items the value :  append( ri!items, {local!newGridRow}).

local!newGridRow was constucted by him as a local variable by using a type constructor like: local!newGridRow: 'type!{urn:com:appian:types}EPR_items'().

I assume this leads to a constructed but empty dataStructure where all values of the variables in the CDT items are 'null', wether they are of type number, decimal, or boolean and "" when text.

At least that happens with the CDT "departments" which I use when I try to adapt the example .

My local!newGridRow Variable looks like this:

department

    • departmentid null(Number (Integer))
      • name ""(Text)
        • order null(Number (Integer))
          • isactive null(Boolean)

          The tutor uses a dropdown field in his example on the text field 'category'.

          Appending the new row local!newGridRow into his r!items list works, because inserting a "" into a list of text at position category in the CDT items is possible and therefore the dropdown field is consistent afterwards with text values in his choiceLabels and choiceValues list.

          Now my question:

          In my case I decided to use the 'order" field in the dropdown field, which is an integer.

          When I use the same statement to append the new row to the list I receive the following error message:

          "Could not display interface. Please check definition and inputs. Interface Definition: Expression evaluation error at function a!forEach [line 47]: Error in a!forEach() expression during iteration 1: Expression evaluation error at function a!dropdownField [line 72]: A dropdown component [label=“Dropdown”] has an invalid value for “choiceValues”. Choice values cannot be null."

          I guess the reason for this error is that after constructing the local variable local!newGridRow the value of the order property is "null", which in turn appending to the depatments (aka items) list results in a null in an integer field.

          And the dropdown field crashes, because it cannot compute a null value in a dropdown field, which is exactly what the error message states.

          But what can I do about it?

          I expected the dropdownfield to show the "Please selcect a value" message in case the value for this field is not set or null.
          How can I force appian to create the type with a default value "0" at the order property or how can I prevent the dropdown field from crashing???

          (Hint: in my variant I tried to use a dynamic generated list of  choices and values because it is the field 'order' and I thought it might be a good usecase to use the dropdownfield to manually bring my departments in a order, which urges me to add max(order+1) as the new 'order' list entry for a new row later. but I did not reach that point....)

          thanks for your advice.

            Discussion posts and replies are publicly visible

          • This is one of those tricky cases where there is a simple solution that isn't obvious from the error message. In general the error you see can happen in one of two cases:

            1. The current value doesn't match list of values in the choiceValues list.
            2. Your current value is null AND you don't have a placeholderLabel

            The placeholderLabel is any text string to display when your value is null. So, the easiest way to fix this is actually to add placeholderLabel: "Select a value..." or something similar. Then, when the value is null, it should show the text string you provide for the placeholder without an error.

          • 0
            A Score Level 1
            in reply to Peter Lewis

            Thank you Peter. I am really thankful that you try to help me here. (And by the way I enjoed watching your tutorial videos :))

            ..checked the code and ...unfortunately the placeholder Label property is set. look:

            a!dropdownField(
                              label: "Dropdown",
                              labelPosition: "ABOVE",
                              placeholderLabel: "--- Select a Value ---",
                              choiceLabels: local!choiceOfOrderLabels,
                              choiceValues: local!choiceOfOrderValues,
                              saveInto: {
                                fv!item.order
                              },
                              disabled: true,
                              validations: {}
                            ),

            I have a feeling that it must be the first point on your list, but can not yet pinpoint the reason....hmmm...

            my interface:

            a!localVariables(
              local!choiceOfOrderLabels: ri!departments.order,
              local!choiceOfOrderValues: local!choiceOfOrderLabels,
              local!newGridRow: 'type!{urn:com:appian:types}ita_department'(),
              /*local!newGridRow : cast('type!{urn:com:appian:types}ita_department',{0, "leer", 0, false}),*/
              a!formLayout(
                label: "Form",
                contents: {
                  a!gridLayout(
                    label: "Department List",
                    labelPosition: "ABOVE",
                    headerCells: {
                      a!gridLayoutHeaderCell(
                        label: "ID"
                      ),
                      a!gridLayoutHeaderCell(
                        label: "Name"
                      ),
                      a!gridLayoutHeaderCell(
                        label: "Order"
                      ),
                      a!gridLayoutHeaderCell(
                        label: "isActive?"
                      ),
                      a!gridLayoutHeaderCell(
                        label: "Delete?"
                      )
                    },
                    columnConfigs: {
                      a!gridLayoutColumnConfig(
                        width: "DISTRIBUTE"
                      ),
                      a!gridLayoutColumnConfig(
                        width: "DISTRIBUTE",
                        weight: 3
                      ),
                      a!gridLayoutColumnConfig(
                        width: "DISTRIBUTE"
                      ),
                      a!gridLayoutColumnConfig(
                        width: "DISTRIBUTE"
                      ),
                      a!gridLayoutColumnConfig(
                        width: "ICON"
                      )
                    },
                    rows: a!forEach(
                      items: ri!departments,
                      expression: {
                        a!gridRowLayout(
                          contents: {
                            a!integerField(
                              label: "Integer",
                              labelPosition: "ABOVE",
                              value: fv!item.departmentid,
                              saveInto: {
                                fv!item.departmentid
                              },
                              refreshAfter: "UNFOCUS",
                              validations: {}
                            ),
                            a!textField(
                              label: "Text",
                              labelPosition: "ABOVE",
                              value: fv!item.name,
                              saveInto: {
                                fv!item.name
                              },
                              refreshAfter: "UNFOCUS",
                              validations: {}
                            ),
                            a!dropdownField(
                              label: "Dropdown",
                              labelPosition: "ABOVE",
                              placeholderLabel: "--- Select a Value ---",
                              choiceLabels: local!choiceOfOrderLabels,
                              choiceValues: local!choiceOfOrderValues,
                              saveInto: {
                                fv!item.order
                              },
                              disabled: true,
                              validations: {}
                            ),
                            a!radioButtonField(
                              label: "Radio Buttons",
                              labelPosition: "ABOVE",
                              choiceLabels: {
                                "Yes",
                                "No"
                              },
                              choiceValues: {
                                true,
                                false
                              },
                              value: fv!item.isactive,
                              saveInto: {
                                fv!item.isactive
                              },
                              choiceLayout: "STACKED",
                              validations: {}
                            ),
                            a!linkField(
                              label: "Link",
                              labelPosition: "ABOVE",
                              links: {}
                            )
                          }
                        )/*a for each */
                        
                      }
                    ),
                    selectionSaveInto: {},
                    validations: {},
                    shadeAlternateRows: true,
                    addRowLink: a!dynamicLink(
                      label: "addRow",
                      saveInto: a!save(
                        target: ri!departments,
                        value: append(
                          ri!departments,
                          {local!newGridRow}
                        )
                      )
                    )
                  )/* grid layout*/
                  
                },
                buttons: a!buttonLayout(
                  primaryButtons: {
                    a!buttonWidget(
                      label: "Submit",
                      submit: true,
                      style: "PRIMARY"
                    )
                  },
                  secondaryButtons: {
                    a!buttonWidget(
                      label: "Cancel",
                      submit: true,
                      style: "SECONDARY"
                    )
                  }
                )
              )
            )

            and my rule input is:

            departments (List of ita_department)

            List of ita_department:

            5 items

            ita_department department
            id: 3
            name: "Accounting"
            order: 3
            isactive: true

            ita_department department
            id: 2
            name: "Applied Sport and Exercise Science"
            order: 2
            isactive: true

            ....

          • 0
            A Score Level 1
            in reply to aveldena

            when i change local!choiceOfOrderLabels & Values to static lists like this

            local!choiceOfOrderLabels: {1,2,3,4,5},
             local!choiceOfOrderValues: local!choiceOfOrderLabels

            (..and add value: fv!item.order, even though this has nothing to do with the error...)

            the error is gone....

            That is understandable, because the null value is no longer inserted in the list. That is positive.

            Negativ is , that my idea of an "ordered list" will not work this way but this is another story and I skip this till later Slight smile

          • 0
            Appian Employee
            in reply to aveldena

            Ah okay, I know what the issue is - there is a third possible reason for this issue: if the choiceValues list itself has a null! In your case, your choiceValues list is coming directly from ri!departments.order. However, that variable is also the same one you update when adding a new row (and you're adding an empty order to the list). So initially your choice values are {2,3}, but when you add a new row, your list ends up as {2,3,null} and the null isn't allowed in the choice values list.

            From your description, it looks like you're trying to set up a way to reorder items in the grid. Have you tried something like this?

          • 0
            A Score Level 1
            in reply to Peter Lewis

            yep: that's what I wrote . "...., because the null value is no longer inserted in the list. That is positive."

            And the other  idea in the link is definitly a solution.

            It is a total  different approach than my odd one , but...at least it will work.

            Thx again.

            It's a pleasure.

          • 0
            Appian Employee
            in reply to aveldena

            I think if you do want to keep something more similar to your approach you have here, you could enumerate the list of values based on how many items are in the list. For example, if you have 3 rows, you should always have a list of {1,2,3}; so you can set your choiceValues as the following to generate the list:

            enumerate(length(ri!departments.order)) + 1