Skip to main content
June 11, 2021
Solved

Error passing data from process model to interface

  • June 11, 2021
  • 8 replies
  • 0 views

I have an interface that has four dropdown components with dynamic choiceValues based on a query. When a value in the first dropdown is selected, it filters the values of the second dropdown. The second dropdown filters the third and the third dropdown filters the fourth. Each dropdown is disabled until a value is selected from each of the previous dropdowns. This works perfectly in the interface. 

However, in the process model there is an option to "edit existing equipment" that will query a database and fill in fields in the interface, possibly including the four dropdown components mentioned above. When I test this process, I get an error that seems to be telling me that a query for one of the dropdowns in the interface is returning null when it shouldn't. 

Hopefully this makes sense, please feel free to ask for clarification on anything. I have included the relevant code below. Thank you in advance for your help!

Here is the query in the interface that generates the choiceValues for the dropdown component that I'm getting the error in:

local!frameType:
  /*if(*/
    /*and(*/
      /*not(isnull(ri!manufID)),*/
      /*not(isnull(ri!Model))*/
    /*),*/
    a!queryEntity(
      entity: cons!Pump_Frame_Unique,
      query: a!query(
        selection: a!querySelection(
          columns: { a!queryColumn(field: "frametype") }
        ),
        logicalExpression: a!queryLogicalExpression(
          operator: "AND",
          filters: {
            a!queryFilter(
              field: "mfgid",
              operator: "=",
              value: ri!manufID
            ),
            a!queryFilter(
              field: "model",
              operator: "=",
              value: ri!Model
            )
          },
          ignoreFiltersWithEmptyValues: true
        ),
        pagingInfo: a!pagingInfo(
          startIndex: 1,
          batchSize: - 1,
          sort: a!sortInfo(field: "frametype", ascending: true)
        )
      ),
      fetchTotalCount: true
    ).data,
    /*null()*/
  /*),*/

choiceLabels and Values in the related dropdown component:

choiceLabels: {
                    index(local!frameType, "frametype", " "),
                    "OTHER"
                  },
                  choiceValues: {
                    index(local!frameType, "frametype", " "),
                    "OTHER"
                  },

This is the contents of the "value" field in the data tab of the user task node in the process model:

= rule!QueryExistingSurvey(
  custName: pv!Cust_Name,
  locName: pv!Loc_Name,
  equipNo: pv!editEquipNo,
  field: "frametype"
)

rule!QueryExistingSurvey:

keyval(
  a!queryEntity(
    entity: cons!application_view_report,
    query: a!query(
      selection: a!querySelection(columns: a!queryColumn(field: ri!field)),
      logicalExpression: a!queryLogicalExpression(
        operator: "AND",
        filters: {
          a!queryFilter(
            field: "customerName",
            operator: "=",
            value: ri!custName
          ),
          a!queryFilter(
            field: "locationName",
            operator: "=",
            value: ri!locName
          ),
          a!queryFilter(
            field: "equipmentId",
            operator: "=",
            value: ri!equipNo
          )
        },
        ignoreFiltersWithEmptyValues: true
      ),
      pagingInfo: a!pagingInfo(startIndex: 1, batchSize: - 1)
    ),
    fetchTotalCount: false
  ).data[1],
  ri!field,
  ":",
  "]"
)

    Best answer by mikes0011
    rule!QueryExistingSurvey() is mapped to the majority of the node inputs in the "Edit Equipment" node with only the "field" property changing for each input.

    Why are you doing this?  The overall effect is that you'll be repeating the same query over and over again just to pull a different field from each run.  Unless I'm missing something, a much better way (and the standard way) would be to handle this in local variables on your task form itself.  For one thing, that makes it substantially easier to troubleshoot.  And then of course, it means you only need to run the query once, saving the result into a local variable, then (if needed) create local variables where you pull out the property for each "field" type you need.

    8 replies

    mikes0011
    Brainy
    June 11, 2021

    Why are you calling keyVal() in your rule rule!QueryExistingSurvey?  It looks like you're attempting to call it on straight dictionary data returned from QueryEntity, and I would start with the assumption that keyVal() would not work because it's intended to operate on a text value.  If you're just trying to get a property from a dictionary based on a passed-in field name, you should be using the property() function instead.

    What is the result of this rule when you run it, and what data type does it end up being?

    The Expression Guru
    jackf0001Author
    June 11, 2021

    I'm using keyVal to essentially replace the dot operator at the end of the query since "data.ri!field" is not valid. I use ri!field to improve the usability of the rule. When I test the rule I get the result I expect. For example, the keyVal takes "{manuf: SULZER}" and outputs "SULZER" as a text string.

    I did recently learn that the index function can also be used for this.

    mikes0011
    Brainy
    June 11, 2021

    I'd strongly encourage you to use property() instead of the way you're doing it currently.  Namely because there's no guarantee that the result from a query will continue behaving this way in the future.  Also, i'm fuzzy on this but I'd expect your rule will return a singular text value (due to keyval()), where depending on the query results we'd expect it to be an array (though i'm admittedly not as familiar with keyval() so I might be off base here).

    index() and property() are synonymous, allegedly functionally identical rules, but for code clarity (etc), my best practice is to only use index() when getting an index (array position), and use property() when getting a [dot] property.  (And yes this is a hill I'll die on, lol).

    The Expression Guru