e.g. while current is UI. After some async service done, and we want to push relevant change to component. e.g. model
current.access(new Command() {
@Override
public void execute() {
getElement().executeJs("this.widget.refresh(window.JSON.parse($0))", model);
}
});
no change on screen until doing e.g. mouse click event on page. Tried to use the accessSynchronously also. same problem. Changes appear only after 'touching' the screen.
no error/exceptions in console or logs.
Use from component that created using the @JavaScript annotation. working synchronously works fine, but when trying to be asych, seems that render stack somewhere. tried with Vaadin 24.10.1 and 24.3.3
When you want to modify the UI from an async Thread* using ui.access(() -> {...})
, then you need to have the @Push
notification on your View (or one of its "parent" routerLayout-views).
Otherwise that ui modification will show up only after your next server roundtrip (any user interaction in the UI -> button click, etc).
You can use @Push(PushMode.MANUAL)
if you intend to invoke ui.push()
after each call of ui.access(..)
.
Or you can simply use @Push
which will default to PushMode.AUTOMATIC - automatically pushing any changes that were made when the ui-lock from a ui.access(..)
call is lifted
Sidenote: Even though I mostly use automatic pushmode, it has occurred to me that I'd still need to call ui.push()
sometimes for it to work. I am not sure if that was a bug or an intentional edge-case.
* or within e.g. a click listener of a Button
if you want the modification to show before the whole clicklistener has completed (most common use case for me)
PS: you can simplify your code with a lambda expression:
current.access(() -> getElement().executeJs("this.widget.refresh(window.JSON.parse($0))", model));