Starting process from UI - local variables vs rule inputs

Hi,

I have the following situation:

- one interface that is embedded inside the other larger interface

- first interface has non submit button that starts process upon click

- first interface has 4 rule inputs that are used as parameters for starting the process

- these 4 rule inputs are calculated also on the button click, just before sending them to process as parameters

Behavior on test:

- if I test this interface "manually" from designer, process is successfully started and all the parameters are passed to the process

- if I test this interface through the process which contains its "parent" interface, parameters are not forwarded

So, this code for the first interface doesn't work:

a!localVariables(
...
    a!buttonLayout(
        primaryButtons: {
            a!buttonWidget(
                label: "Start process",
                saveInto: {
                  a!save(
                    ri!firstProc_cdt,
                    rule!DLS_mapFirstProcParam(
                      input: local!valuesOne
                    )
                  ),
                  a!save(
                    ri!secondProc_cdt,
                    rule!DLS_mapSecondProcParam(
                      input: local!valuesTwo
                    )
                  ),
                  a!save(
                    ri!thirdProc_cdt,
                    rule!DLS_mapThirdProcParam(
                      input: local!valuesThree
                    )
                  ),
                  a!save(
                    ri!fourthProc_cdt,
                    rule!DLS_mapFourthProcParam(
                      input: local!valuesFour
                    )
                  ),
                  a!startProcess(
                    processModel: cons!PROCESS,
                    processParameters: {
                      paramOne: ri!firstProc_cdt,
                      paramTwo: ri!secondProc_cdt,
                      paramThree: ri!thirdProc_cdt,
                      paramFour: ri!fourthProc_cdt
                    }
                  )
                }

and this one does work:

a!localVariables(
local!firstParam,
local!secondParam,
local!thirdParam,
local!fourthParam,
...
    a!buttonLayout(
        primaryButtons: {
            a!buttonWidget(
                label: "Start process",
                saveInto: {
                  a!save(
                    local!firstParam,
                    rule!DLS_mapFirstProcParam(
                      input: local!valuesOne
                    )
                  ),
                  a!save(
                    local!secondParam,
                    rule!DLS_mapSecondProcParam(
                      input: local!valuesTwo
                    )
                  ),
                  a!save(
                    local!thirdParam,
                    rule!DLS_mapThirdProcParam(
                      input: local!valuesThree
                    )
                  ),
                  a!save(
                    local!fourthParam,
                    rule!DLS_mapFourthProcParam(
                      input: local!valuesFour
                    )
                  ),
                  a!startProcess(
                    processModel: cons!PROCESS,
                    processParameters: {
                      paramOne: local!firstParam,
                      paramTwo: local!secondParam,
                      paramThree: local!thirdParam,
                      paramFour: local!fourthParam
                    }
                  )
                }

Basically, only difference is that in the first example rule inputs of the interface are used as input parameters for process model. In the second one there are no rule inputs, only local variables. They have the same content since expression rules for mapping create the same data type as the rule inputs.

Can someone explain to me why parameters were null in process instance monitoring in the case when rule inputs are used. Are rule inputs "evaluated" at some other point in time than local variables when interface is used as component of larger interface and inside the process model?

  Discussion posts and replies are publicly visible

  • Hi,

    I could recreate your issue, only when, in the parent interface when we send the rule input to explicitly defined as NULL keyword.

    child interface - retails

    a!localVariables(
      local!first,
      a!buttonLayout(
        primaryButtons: a!buttonWidget(
          label: "start process",
          saveInto: {
            a!save(ri!data, "vamsi"),
            a!startProcess(
              processModel: cons!PM_CONSTANT,
              processParameters: { input: ri!data }
            )
          }
        )
      )
    )

    parent interface

    a!localVariables(
      local!data,
      {
        rule!retails(data: null),
        rule!retails(data: local!data)
      }
    )

    Line 4 in parent interface, sent null values to input param in PM

    Line 5 sent input param value from children interface as "vamsi"

    Even though they are typically the same.

  • I think we have a little misunderstanding here Slight smile

    Parent interface doesn't send any values into those rule inputs (it does to other 2 rule inputs but it seems that everything works fine with that part and they are not important for this case). They are just "defined" in parent interface.

    I just had idea to return calculated values  from child interface back to the parent interface through these rule inputs since they may be necessary for further usage (my child interface should be reusable in many interfaces).

    These rule inputs are calculated and used only in child interface.

    So, basically they are sent into child interface as nulls (but not explicitly), but for some reason not refreshed after calculations and button clicking in that same child interface.  

  • I think the issue can probably be at parent interface where you are mapping rule inputs to sub-interface, please make sure those mappings are present.

  • This is the way I tried to make it work and it failed:

    1) Child interface code (copied from first post):

    a!localVariables(
    ...
        a!buttonLayout(
            primaryButtons: {
                a!buttonWidget(
                    label: "Start process",
                    saveInto: {
                      a!save(
                        ri!firstProc_cdt,
                        rule!DLS_mapFirstProcParam(
                          input: local!valuesOne
                        )
                      ),
                      a!save(
                        ri!secondProc_cdt,
                        rule!DLS_mapSecondProcParam(
                          input: local!valuesTwo
                        )
                      ),
                      a!save(
                        ri!thirdProc_cdt,
                        rule!DLS_mapThirdProcParam(
                          input: local!valuesThree
                        )
                      ),
                      a!save(
                        ri!fourthProc_cdt,
                        rule!DLS_mapFourthProcParam(
                          input: local!valuesFour
                        )
                      ),
                      a!startProcess(
                        processModel: cons!PROCESS,
                        processParameters: {
                          paramOne: ri!firstProc_cdt,
                          paramTwo: ri!secondProc_cdt,
                          paramThree: ri!thirdProc_cdt,
                          paramFour: ri!fourthProc_cdt
                        }
                      )
                    }

    2) Parent interface code part with child interface reference:

    a!boxLayout(
                        style: "ACCENT",
                        label: "Child interface",
                        isCollapsible: true,
                        isInitiallyCollapsed: true,
                        contents: rule!childInterface(
                          input_one_cdt: ri!input_one_cdt,
                          input_two_cdt: ri!input_two_cdt,
                          input_three_cdt: ri!input_three_cdt,
                          firstProc_cdt: ri!firstProc_cdt,
                          secondProc_cdt: ri!secondProc_cdt,
                          thirdProc_cdt: ri!thridProc_cdt,
                          fourthProc_cdt: ri!fourthProc_cdt
                        )
                      )

    Nevertheless, these rule inputs have nothing to do with parent interface. They are first calculated and used inside the child interface. There they are sent to process as empty.

    I think it could be useful for them to be saved and returned to parent interface for future use. However, even without it they are not properly forwarded into process model started from within the child interface. That's the thing that puzzles me.

  • 0
    Certified Lead Developer
    in reply to ivanm0004

    Are the local displayed in UI designer with proper values? Are the PVs in process configured as parameters?

  • Yes, everything works fine if I set some test data in child interface designer view and click button. I believe that means everything is correctly coded and configured.

    However, if I put this interface inside parent interface it stops working.

    I've also tried to call this child interface from parent interface without referencing these rule inputs since they are first calculated and used only in child interface but that didn't work to:

    a!boxLayout(
                        style: "ACCENT",
                        label: "Child interface",
                        isCollapsible: true,
                        isInitiallyCollapsed: true,
                        contents: rule!childInterface(
                          input_one_cdt: ri!input_one_cdt,
                          input_two_cdt: ri!input_two_cdt,
                          input_three_cdt: ri!input_three_cdt
                        )
                      )

    Inputs are some data that need to be forwarded from parent interface and used in child interface and those other 4 rule inputs (removed from the last code snippet) were empty placeholders for data that will be calculated inside the child interface just before starting the process.

    So, process should be independent from the parent interface and rule inputs used for the process should be returned to parent interface so they can be used further for logging purposes or anything else.

  • 0
    Certified Lead Developer
    in reply to ivanm0004

    OK. There is so many things going on ... When I have a bug I try to simplify things and narrow down.

    So, when you open the parent interface in designer and click the button, do you see the rule inputs and locals being updated?

  • I can't see locals that exist only in child interface from the parent interface designer view. Or I just don't know how?

    Rule inputs that should be populated inside the child interface and returned to the parent interface remain empty in the parent interface designer view after button click.

  • 0
    Certified Lead Developer
    in reply to ivanm0004

    OK. Quick clarification. In Appian there is no "sending" and "returning" of variables in UI. It is more like sharing a reference.

    So you have a parent interface with a rule input, you assign this to a child interface with a similar rule input. Now  changing the value in the child does not work.

    Please add a textfield inside the child to see the actual value of the variables inside.