Error with cascading drop down

I have two level cascading dropdown in an editable grid. In the grid there is a "Add new row" which adds a new row on every click. 

The issue is with the variable (local!items) I am using to generate the choice values of the second drop down (Item drop down). For the first row in the grid, it populates correct, but when user clicks to add second row and then try to select values in first dropdown, then it shows error.

I know the reason why the error as the variable is not updating on every new row addition. I'm unable to figure out the way and have hard time resolving this error.

Attached is the snippet of code I have and screenshot of error.

Any help is highly appreciated.

Thanks!

a!localVariables(

  local!supplyType: rule!OSR_QRY_T_Ref_getSupplyTypeDataByID(
    isActive: true()
  ), /* Gets all items in supply table to be used as Category */

  local!items,
  
  /* Code snippet starts here, these dropdowns are in foreach() of editable grid*/
             /* fv!item is a request row in editable grid */ 
              a!dropdownField(      /* first dropdown */
                label: "category " & fv!index,
                placeholderLabel: "---Please select Category---",
                choiceLabels: local!supplyType.data.SupplyTypeName,
                choiceValues: local!supplyType.data.SupplyTypeID,
                value: index(
                  fv!item,
                  "SupplyTypeID",
                  {}
                ),
                saveInto: {
                  fv!item.SupplyTypeID,
                  a!save(
                    local!items,             /* On every interaction with Category dropdown, this should be updated but it's not updating for items while generating a new row */ 
                    rule!OSR_QRY_T_Ref_getItemDataByID(
                      isActive: true(),
                      supplyTypeID: index(
                        fv!item,
                        "SupplyTypeID",
                        {}
                      )
                    ).data /* Gets Items in a specific supply category */
                  ),
                  a!save(
                    fv!item.ItemID,
                    null
                  )
                }
              ),
              
              a!dropdownField(         /* second dropdown */
                label: "item " & fv!index,
                placeholderLabel: "---Please select Item---",
                choiceLabels: index(
                  local!items,
                  "ItemName",
                  {}
                ),
                choiceValues: index(
                  local!items,
                  "ItemID",
                  {}
                ),
                value: index(
                  fv!item,
                  "ItemID",
                  {}
                ),
                saveInto: fv!item.ItemID
              )
)

  Discussion posts and replies are publicly visible

Parents
  • 0
    Certified Lead Developer

    This is a really sticky situation.

    So what I think is happening is that you have 1 array of items.  That stores all the choice values for a possible list of items.  What can be contained in that list is determined by what you choose in ANY of the category dropdowns.  You only have one list.  It can be updated by any dropdown.  That means, absolutely all of the category dropdowns have to have exactly the same setting or it won't work.  Because each of the items dropdowns will only be running off the same list.

    you now have: 

    {4, 11, 3}

    What you need is:

    {

    {4, 11, 3},

    {8, 12, 5, 27}, /*whatever the real numbers are*/

    {1, 2, 6, 9},

    {4, 11, 3},

    }

    You're going to be creating a dynamically expanding list of lists. You need to create local!items as an empty list of lists to start. 

    local!items: {}, (You may have to start with {{}} to make sure append function doesn't produce a flat array)

    Now, when you create a row, you have to save a dropdown index and append an empty list to the end of local!items.

    Each one of your category dropdowns has to a!save not to local!items, like it does now, but a!save to local!items[dropdownIndex].  When you delete a row, if you allow such a thing, you'll have to remove the whole list, local!items[dropdownIndex], from local!items.

    The new feature of 20.1 to look at your local variables is going to be invaluable in seeing what's going on.

  • 0
    Certified Lead Developer
    in reply to Dave Lewis
    You need to create local!items as an empty list of lists to start.

    Wouldn't it be quite a bit simpler to define a separate local!items variable within every grid row, like I suggested above?  Appian doesn't really handle lists of lists in any sort of easily-usable way, in my experience.

  • 0
    Certified Lead Developer
    in reply to Mike Schmitt

    Poster is already utilizing a forEach.  The fv!index automatically solves the "dropdownIndex" problem.  So yes, using a!forEach to construct it, you need to make sure that there's a different variable, (or different portion of a variable) for each list of dropdown options that can dynamically change.

    Your problem is that you only had one, so each of the dynamic dropdowns all switch when you change any category.

  • 0
    Certified Lead Developer
    in reply to Dave Lewis
    and as far as I am aware would require the same variables being redefined every time the a!forEach is run, which is every time anything gets changed?

    That's not the way a!localVariables() works, luckily.  By default it only refreshes its definition anytime one of its referenced values changes.

    It would need to be implemented with care to avoid causing a performance hit, since essentially we're loading a separate local!items for every member in the grid row, but assuming that the target item list isn't querying hundreds of items from the DB every time or something, I'd expect it should work OK.

Reply
  • 0
    Certified Lead Developer
    in reply to Dave Lewis
    and as far as I am aware would require the same variables being redefined every time the a!forEach is run, which is every time anything gets changed?

    That's not the way a!localVariables() works, luckily.  By default it only refreshes its definition anytime one of its referenced values changes.

    It would need to be implemented with care to avoid causing a performance hit, since essentially we're loading a separate local!items for every member in the grid row, but assuming that the target item list isn't querying hundreds of items from the DB every time or something, I'd expect it should work OK.

Children
No Data