Refresh Interface after a!startProcess does not work

Certified Senior Developer

Hi,

We have a simple interface wich contains a refresh button that triggers a a!startProcess() function (to update some fields in Db and then update fields in the GUI). 
The interface is displayed from a RecordType view.
The process gets some data and then write simply the current datetime into an updated_on field in the table. 
The problem we met is when we click on the button, the data are not refreshed (or works just the first time). 
When we debug the variables in the interface we can see that the data are still the Old ones despite the fact the data are correct in the Db table. 
If we click again and again, the data are never refreshed. 
I've tried a lot of things :
- add a counter in the interface to ensure the save is called when the process ended
- all the process nodes are well chained. 
- I've deleted a lot of nodes in the process so that now it contains only 5 nodes (to be sure, to avoid the 50 nodes issues). 
- I've created a little testing snippet example and all works fine in another environment (with a Site, a RecordType, a process, a simple Interface and the Vehicle CDT example).

Would you have any idea why this problem occurs ? 


Regards 

  Discussion posts and replies are publicly visible

Parents Reply Children
  • 0
    Certified Senior Developer
    in reply to cedric01

    Does onSuccess() really executed after the last process node (on the end event) ?

  • 0
    Certified Senior Developer
    in reply to cedric01

    I've finally found a solution:

    Using pv!processInfo to get back the last updated data.
    (Calling the ER from onSuccess() event does not work)

  • 0
    Certified Lead Developer
    in reply to cedric01
    Calling the ER from onSuccess

    Check your ER.  If you have any local variables in it, they're probably not set to "refresh always", and therefore won't automatically re-execute even when you think it should (i.e. when called in your onSuccess parameter).  One way I've gotten around this in the past is to pass a refresh counter into the ER itself, so it only refreshes when i want it to.  That gives you the additional advantage wherein you can just have your onSuccess paramter increment your refresh counter, and use the initial query done in your variable declarations (when applicable).

  • 0
    Certified Senior Developer
    in reply to Mike Schmitt

    Thank you Mike for your tips. My ER were indeed containing a local!variable.
    After setting this one to Refresh always = True, it works fine.

    But is it not a little tricky ? It means any ER without localvariable works like in an implicit always-refresh mode, and when you add a localVar, it works as a default NOT refresh-always mode.

  • 0
    Certified Lead Developer
    in reply to cedric01

    you need to consider what the implications of any local variable declared through a!localVariables() is.

    All variables declared using default settings (i.e. with no refreshVariable override) implicitly assumes that "REFRESH ON REFERENCED VAR CHANGE" will be ON, and that all other refreshes will be OFF.

    In this way, a local variable works a LITTLE like the legacy LOAD() variables, except that those didn't even refresh on referenced variable change (making many desired operations harder, as they had to be manually refreshed no matter what).

    The side effect of this is, when you set certain variables in an expression rule, you need to be careful that they wouldn't need to refresh in an interface context - AFAIK, even if you call the same ER multiple times in an interface, the way Appian flattens and caches the loaded data, it's treated as if it's one instance called (but will be re-run in any varying places it's called, but those places will still only call the same cached instance).

    As I've said, the strongest way to handle this is to anticipate it and pass in a refresh trigger RI to your expression rule, and use it in the "REFRESH ON VAR CHANGE" paramter for some local variable, particularly in cases where refreshing one local variable will cause its value to change and cascade to any other local variable declarations in the rule.

  • 0
    Certified Senior Developer
    in reply to Mike Schmitt

    That's very interested.
    Mike, would you have a little example of what you are describing please ?
    I'm not sure to understand what type to pass to the ER, and how to configure refreshvariable in ER or Interface.

  • 0
    Certified Lead Developer
    in reply to cedric01

    Sure - if you can post the code for `as_qe_getHistoryWithFilters()` (or a slightly simplified version of it, it doesn't need to be working etc, just need to see the structure), i'll post the revised version i'd suggest which should make it refresh only when triggered from the calling parent interface.

  • 0
    Certified Senior Developer
    in reply to Mike Schmitt

    Here it is:

    a!localVariables(
      local!cdt: a!refreshVariable(
        value: a!queryEntity(
          entity: cons!AS_DSE_HISTORY,
          query: a!query(
            logicalExpression: a!queryLogicalExpression(
              operator: "AND",
              filters: {
                a!queryFilter(
                  field: "history_id",
                  operator: "=",
                  value: ri!historyId,
                  applyWhen: a!isNotNullOrEmpty(ri!historyId)
                ),
              }
            ),
            pagingInfo: a!pagingInfo(
              startIndex: 1, 
              batchSize: - 1,
              sort: a!sortInfo("history_id", true)
            )
          )
        ).data,
        refreshAlways: ri!refreshAlways
      ),
      local!cdt, /* I just keep this local!var for the Example */
    )

  • 0
    Certified Lead Developer
    in reply to cedric01

    May I ask the question of what purpose this local variable has? You can just leave it away and avoid the hassle with the refreshes.

  • 0
    Certified Senior Developer
    in reply to Stefan Helzle

    Stefan, I add a little comment to my code, to avoid you to ask this question ;-)
    this local variable will be used for an updateDictionary needs.