Auto-refresh Local Variable via Asynchronous Process

All,

Let's say I have an interface with a button widget, which triggers an asynchronous process (i.e., a!startProcess). There's also a local variable (let's call it local!myVar) that is initially empty. My goal is to display the value of this variable when it's updated. The asynchronous process is to determine what value gets assigned to this local variable. And I'm looking for ways to display this value without having to reload/leave the interface.

From what I understand, the use of a!refreshVariable() is probably the best way to make this work, but I'm having some difficulties figuring out how to pass a dynamically assigned value within the asynchronous process back to the interface.

Any tips/pointers will be much appreciated!

  Discussion posts and replies are publicly visible

  • 0
    Certified Lead Developer

    Hi

    you can leverage activity chaining as described in the a!startProcess documentation:

    https://docs.appian.com/suite/help/19.4/Start_Process_Smart_Service.html#leveraging-activity-chaining

    Use the onSuccess option to retrieve the processInfo.pv and update your local using a!save

  • -- Thanks for the response. A couple of follow-up questions:

    • Doesn't the use of activity chaining equate to leaving the interface?
    • If the value assignment in the asynchronous process happens a few minutes after the button is clicked, would your approach still work?
  • 0
    Certified Lead Developer
    in reply to SailingHome
    Doesn't the use of activity chaining equate to leaving the interface?

    a!startProcess isn't strictly "asynchronous" in the way you're thinking.  While it does fire off an instance of the target process without leaving the current interface, the interface itself waits for any chaining to end or be otherwise resolved before it returns the onSuccess parameter info. 

    In this way, chaining can be leveraged to assist in setting the value of one of your local variables with the value of in-process data (nominally at whatever value that PV holds when chaining ends or the process terminates, whichever comes first).

    If the value assignment in the asynchronous process happens a few minutes after the button is clicked

    For this use case, you would need to use some other method of pulling back the process data in question. Particularly, if the data you're expecting takes "a few minutes", then we wouldn't be talking about a process with chaining through it (unless you plan on running some sort of query or expression logic that takes a few minutes to run?).

  • I'd suggest using your a!refreshVariable() to query the data periodically. The main thing you have to figure out is where you need to query. When you update a variable in your process, does it only get updated in the process or do you also save the result to a database table?

    If it only gets updated in your process, you can use the a!queryProcessAnalytics() function. This enables you to query directly from process instances and return their data. In this case, I'd suggest having a!startProcess() return back the process ID. Then, you can use a!queryProcessAnalytics to query the process with the ID provided.

    If you also update the data in the database, you can also use a!queryEntity() to query the data from the database in your refresh variable.

    Assuming you go with the first option, there are several steps you will need to do:

    1) Make sure you return the process ID from a!startProcess() by saving the data from fv!processInfo the "onSuccess" parameter.

    2) Create a process report to return information about the process model you kick off.

    3) Set up your refresh variable like this to query from the process:

    a!localVariables(
      local!processInfo,
      /* This variable should be updated with the onSuccess parameter from a!startProcess() */
      
      local!processStatus: a!refreshVariable(
        value: a!queryProcessAnalytics(
          report: cons!YOUR_REPORT_HERE,
          query: a!query(
            pagingInfo: a!pagingInfo(
              startIndex: 1,
              batchSize: 1
            ),
            filter: a!queryFilter(
              field: "c0",
              /* You might have to change this depending on which column is the ID in */
              /* your process report */
              
              operator: "=",
              value: local!processInfo.pp.id
            )
          )
        ),
        refreshInterval: 1
      )
      ...
    )

  • 0
    Certified Lead Developer

    You can also try the Pusher Component and Connected Systems plugins for this https://community.appian.com/b/appmarket/posts/event-pusher-component-plug-in

    It relies on a third party services, but it has the benefit of having the interface refresh immediately instead of waiting for a refreshVariable cycle. 

  • Big thanks to all who responded to this posting - I found the replies really helpful!

    I think I'm getting close to finding a suitable solution for my need, but here's one final bit of "need" that initially didn't seem that relevant:

    The said asynchronous process involves interactions with an external system. The short end is that the external system will return a Boolean value at the end of the interaction. That's why I stated that it might take a few minutes before the value assignment can happen, but an edge case scenario also warrants the possibility of this handshake taking as long as a few hours.

    A few additional comments:

    • I could have the resulting value be written to the database to make it available for retrieval if necessary, but that isn't part of my approach at this point.
    • Using a plug-in is also an option, but one that I'd like to avoid if at all possible.
    • I'm thinking I should be using the refreshInterval option for a!refreshVariable given the expected delay in getting the value.

    cc:

  • I think given your additional comments, my recommendation still stands. Using a!refreshVariable() and a!queryProcessAnalytics() will allow you to asynchronously access the data and you don't have to write to the database. It can be a little tedious to get it to work though, so please feel free to respond with questions.

  • 0
    Certified Lead Developer
    in reply to SailingHome

    If the handshake time really ends up being a few hours in some cases, i think it's no longer a reasonable expectation that the user is still on the same interface.  In that case, using auto-freshing variables is a moot point; I would strongly urge you to handle this in-process somehow -- for one example, set up a process trigger that kicks off a new task that's assigned to the original user when the handshake is complete, or send the user an email, etc.