Automatical update of an Appian webpage on change of task status? - refresh

We have an Appian grid that shows all Appian tasks of a user. The corresponding data we obtain using queryProcessAnalytics(). How can we make this update automatically when the task status changes?
Currently, we have stored the result of queryProcessAnalytics() in a local variable and we set a!refreshVariables() to refresh this variable on every "user interaction" with refreshAlways: true. We also added a button Refresh that doesn't store anything away, but simply counts as a user interaction when it is clicked. The grid then refreshes automatically when the local variable with the data changes, because the grid is set to refresh when a used/dependent local variable has changed, which mainly means that the user is forced to click on Refresh to ensure to be up-to-date and see latest tasks.
We consider this a workaround as the refresh automatically on variable change in our understanding triggers refresh of local variable (and thus the grid) only once an another local variable changes, but does not trigger a refresh queryProcessAnalytics would suddenly throw a different result.
Any help towards a fully automatical solution is appreciated!
We searched the Appian community but to no avail. Most entries are rather old, e.g.
Grid refresh not working on Load()

You should use refreshInterval within your a!refreshVariables()with value 0,5. It will refresh every 30 seconds.
https://docs.appian.com/suite/help/21.3/fnc_evaluation_a_refreshvariable.html

Related

Document has been modified or corrupted since signed! (data)

I'm working in HCL Notes application. I have developed a summary view to show calculated figures to the user. Then the user clicks one of the action buttons and I open a detailed view, but for that view I setup Selection Formula on the fly so that it shows the records filtered specific to that button conditions. It was working almost fine for a few days, but now most of the time it shows some previously shown (filtered) data no matter what button the user has clicked. Means it doesn't set the Selection Formula of the view and shows the view with the old formula and it won't get back to normal condition even if they restart Notes application.
When the user is stuck in this particular condition, and they peep through the status bar it shows this message:
Document has been modified or corrupted since signed! (data).
The necessary code-snippet is as below:
*Set dtlView = db.GetView("Report_Dtl")
dtlView.SelectionFormula =formula
Call dtlView.Refresh()*
where formula is the dynamically built formula. Looks like the line
dtlView.SelectionFormula =formula
is unable to update the selection formula and then the line below generates the above error message:
Call uidb.OpenView(dtlView.Name,,False, False)
Please help!
Thanks
For "on the fly" modification of the view selection formula your user need "Designer"- access to the database, and that is never a good idea. The help document to the function you are using is explicitly stating that this is not a good idea (emphasise of mine):
This is not a good way to display a selected set of documents for a specific user. When you use this property to change the view selection, it applies to all users of the view.
There are problems with using this method to make a view display a new selection of documents for an end user:
Do not give end-users Designer access to an application.
If it is a shared view, users will interfere with each other's searches.
The Notes® client caches design information, and there's no way to tell it to update its cache (except for outlines). Exiting and re-entering the application usually works, but it's hard to programmatically ensure the user exited the application entirely.
In addition the modification of the view selection formula can break the signature of the design element and then other errors occur.
Better use another approach:
Use a Folder for every user and put the selected documents in there (after doing a NotesDatabase.Search with the formula
Use a separate view for every user and let a server agent manipulate its selection formula with a user that has access.
For having a separate view / folder for every user you could use "Shared, Private on first use"- views (they are not easy to maintain), or any process that generates them and is able to assign every view to the users they belong to... in both cases this needs some effort, but at least it will work.

How to update content in a block after flagging event without page reload?

Hy, I'm fairly new to Drupal 8. I have a custom entity type called Event and using the Flag module I added the option to "Favorite the event" and finally I have a custom block which displays the number of Events each User has favorited. Everytime a user "favorites" a new event the block obviously shows the old value. I have set up cache invalidation, so if the user refreshes the page he will see the updated/correct number. Now my question is, how can I update the block's number without refreshing the page. I can't find an easy example anywhere. The Flag module's docs are outdated or incomplete and I think the answer lies in subscribing to the Flagging event and performing actions there, I just don't know how to include or perform a javascript action ("if it's needed, I assume it is). Any help would be greatly appreciated.
Use Ajax Command on block and don't forget to attach ajax.core library to block.

Ionic 2 - Store user credentials (local storage vs nav params)

I´m developing an Ionic 2 app. When I make login, I could store user credentials on SQLStorage, LocalStorage or transfer it as parameter on NavParam.
Example:
onLogin(){
this.nav.setRoot(MainPageComponent,user);
}
vs
let storage = new Storage(SqlStorage);
storage.set('name', 'Max');
What is the main advantage of storage over passing as parameter?
What is the main advantage of storage over passing as parameter?
If you use that information just in one page or two, you can send it as parameter. But the problem is that you will probably use the name in more than one place (maybe in a settings page, or in the side menu of the app, and so on), so storing that information somewhere would be a good idea so you can get it back when you need to.
Also, if you get that information in one page, and you want to show it in another one, but those pages are not connected directly in the workflow of your app, you would need to pass it through some other pages just to get it where you want to show it. So again, storing that data seems to be a better approach.
Please notice that if you use SQLStorage or LocalStorage, you should set also an expiration date to force the user to log in again after a given period of time.
Navparams is used for transferring the data between pages say, you have to open a particular item's details, you need to click on an Item and the parameters will be sent using Navprams to the itemDescription page.
You prefer localstorage.setItem('userId', $userId), because storing locally will solve the unwanted sign-in every time you open the app.
If you store in your local storage, then on every app on load, we can check the existence of the local variable.
if(localstorage.getItem('userId')==null){
this.signin();
}
else{
this.appOpen();
}
This one can help you!

Refreshing a new document so default displays in computed control

This problem has been bugging me for awhile and I can not seem to get around it. So I stripped it down to the most basic level.
1. created a new XPage and bound it to an exiting form
2. created a panel called 'displayPanel'
3. inside the panel create a comboBox and give it a few values and a default value of any valid value.
4. Set an onChange event that does a partial refresh of displayPanel
5. Add a computed field that simply displays the value of the comboBox.
6 added a button that does a partial refresh of displayPanel onClick.
Open the XPage and the computed field is blank, make a change and the computed field displays.
open the XPage again and click the refresh button and the computed field displays
Now this is a very simple example but what I need to do is actually more complex but the value of the comboBox (Does not need to be a comboBox) is not available until a refresh is performed. This is only an issue on a new document when it first gets it's defaults.
I have added this:
view.postScript("XSP.partialRefreshGet('#{id:displayPanel}')")
to every one of the page events but it does not appear to do an actual page refresh like clicking the button or making a change.
I'm at a loss as to how to make this work. If I could get this simple example to work the rest of what I need is easy.
Thanks
Fredrik is on the right track -- you should set the value manually during an event -- but I would add two caveats:
Call setValue instead of replaceItemValue (e.g. document1.setValue("myComboBox", "Default Value");). The comparative advantages might not be applicable in this specific case, but you should be in the habit of always calling setValue instead of replaceItemValue (and getValue instead of getItemValue) so that, when you've encountered a scenario where it makes a real difference, you just get that benefit for free... the rest of the time, the methods are equivalent, so you might as well just use the one that requires less typing. :)
You'll probably need to do this in afterPageLoad: the data source may not be ready yet during beforePageLoad; depending on why you're referencing the default value elsewhere in your page, beforeRenderResponse might be too late; and afterRenderResponse would definitely be too late...
...which leads me to why the defaultValue attribute does not behave the way we might expect it to, especially for those of us with experience developing Notes client apps.
The XPages engine splits the processing of every HTTP request into several "phases". Depending on the type of request (initial page load, partial refresh event, etc.) and other factors, the lifecycle will consist of as many as 6 phases and as few as 2.
This tutorial page provides an excellent description of these phases, but in the context of this question, the following are specifically of interest:
Apply Request Values
When an event runs against a page that has already been loaded (e.g. a user clicks a button, or selects a value from a combobox that has an onChange event, etc.), the HTTP request sent to the server to trigger the event includes POST data that represents the value of all editable components. This phase temporarily stores these values in the submittedValue property of any affected components, but the data source doesn't "know" what the new values are yet.
Process Validations
This phase runs any applicable validators and, if any fail, skips straight to the last phase (which means it never runs the code of the event that was triggered).
Update Model Values
If no validations fail (or none are defined), this phase takes the submitted values and actually stores them in the corresponding data source. Until this point, the data source is completely unaware that there has been any user interaction. This is intended to avoid prematurely polluting any back end data with user input that might not even be valid. Remember, not every data source is a "document"; it might be relational data that is changed via an UPDATE the instant setValue is called... which is basically what this phase does: it takes the submittedValue and calls setValue on the corresponding data source (and then sets submittedValue to null). This separation allows components to simply be visual representations of the state of the back end data -- visual representations that the user interacts with; our code should always be interacting directly with the back end data via the abstraction layer of a data source.
Render Response
Once all of the other phases have run (or been skipped), this phase sends a response to the consumer. In other words, it sends HTML (or JSON, or XML, or PDF, etc.) back to the browser. But the most salient point in the context of this question is that the prior phases are always skipped on initial page load. When the user first accesses a page, they haven't had a chance to enter any data yet, so there are no request values to be applied. Since no data has been posted, there's nothing to validate. And -- most pertinent of all -- there's nothing to be pushed to the data model. So a representation of the component tree (or a subset of it, in the case of a partial refresh event) always needs to be sent to the user, but until the user interacts with that representation, the data source remains in whatever state it was when the most recent response was rendered... which is why, if you want a specific property of the data source to have a specific value before the user interacts with it, your code needs to set that property's value manually.
In summary, components are visual. Data sources are abstract. Perhaps this behavior would be more self-explanatory if the component property had simply been called defaultClientValue instead of defaultValue, because that's essentially what it is: a default suggestion to the user for what data to send back to the data source. But until they do, the data source has not received that value. So if, on initial page load, you need a data source property to have a value that it wouldn't already have in its default state, you should manually call setValue to give it the desired value.
P.S. Ironically, if you'd called partialRefreshPost instead of partialRefreshGet, you likely would have achieved the result you were looking for, because the former sends all the form data, while the latter just asks the existing component state to be rendered again. But then you're forcing all of the form data to be sent just to update one data source property, so it's better to simply do what's described above.

Synchronizing DataGridView (DataTable) with the DB

I have the following situation: there is a table in the DB that is queried when the form loads and the retrieved data is filled into a DataGridView via the DataTable underneath. After the data is loaded the user is free to modify the data (add / delete rows, modify entries).
The form has 2 buttons: Apply and Refresh. The first one sends the changes to the database, the second one re-reads the data from the DB and erases any changes that have been made by the user.
My question is: is this the best way to keep a DataGridView synchronized with the DB (from a users point of view)?
For now these are the downsides:
the user must keep track of what he is doing and must press the button every while
the modifications are lost if the form is closed / app crash / ...
I tried sending the changes to the DB on CellEndEdit event but then the user also needs some Undo/Redo functionality and that is ... well ... a different story.
So, any suggestions?
I would say that the way you are currently doing it is fine. If you start attempting to update the database while the user is still making edits you can run in to issues updating or modfiying things that the user may ultimately decide they did not want to change. Additionally this has the chance to greatly increase the number of database calls.
Forcing the user to click apply helps ensure that only the changes the user actually wants are sent to the database.
As for losing the changes if the app crashes before applying them, I would be more concernced with why the app is crashing.
The only important thing to remember is that you should refetch the data before saving it and the refetched data should still match the data you originally displayed to the user. If it doesn't, someone else made a change your user will be unknowingly overwriting. Your users probably will not like that.
How you handle this is dependent on what your client needs in their database.