Where to store `UI`-object scoped state in a Vaadin 14 app?
Asked Answered
J

1

4

Context (web app)

To store state available to our entire Vaadin app, we can get and set "Attribute" on the VaadinContext object that represents our entire Vaadin-based web app at runtime. These attributes act as a key-value collection, where the key is of type String and the value is of type Object.

We access the context by calling UI.getCurrent().getSession().getService().getContext().

Session (per user)

To store state available to any one user’s session, we can similarly get and set "attributes" on the VaadinSession object.

We access the session by calling UI.getCurrent().getSession().

UI (web browser window/tab)

These two levels of scope, context & session, are wrappers around their equivalents defined in the Java Servlet specification. But Vaadin effectively has a third, finer level of scope. Vaadin supports multi-window apps, where each web browser window (or tab) has its own content handled by a UI object. If a user has three windows open within our Vaadin app, that user has three UI object instances on the server housed within a single VaadinSession object.

So it seems like a common need would be storing state per UI (web browser window/tab). So I would expect to see the same kind of getAttribute & setAttribute methods on UI as seen on VaadinSession & VaadinContext. But, no, I do not see such methods on UI.

➥ Is there an appropriate place to store state per UI object?

In the olden days, in previous generations of Vaadin, we always wrote our own subclass of UI. So we could always store state by defining member variables on our own UI-subclass. Now, in the days of Vaadin Flow (v10+, currently 14), we are discouraged (forbidden?) from writing a subclass of UI.

Before filing a feature-request for such attributes, I want to ask if I missed out on a usual place where folks store their per-UI state in current Vaadin-based apps.

Janik answered 19/8, 2019 at 22:38 Comment(1)
A
2

In Vaadin Flow there is ComponentUtil helper class which has methods to store data with components and UI.

See the pair of ComponentUtil.setData methods, one taking a Class as key, the other taking a String as key, just like the getAttribute/setAttribute methods found on VaadinContext & VaadinSession.

Aliped answered 20/8, 2019 at 3:30 Comment(4)
Thanks for your reply and your solution. I did go ahead and open feature-request ticket # 6287.Janik
Bug? Your approach fails because the UI object is being rapidly and inexplicably re-instantiated over and over again. Create a new Vaadin 14 app, in the "Plain Java Servlet" flavor. Attach an implementation of VaadinServiceInitListener, and then add a listener for UIInitEvent as shown in the manual. Put a System.out.println call in that listener. You will see new UI instances being generated even as you click the "Click Me" button of the default app. Shouldn't the UI object be stable for the entire time that browser window/tab is open?Janik
I posted an example app showing this seemingly crazy UI class behavior on the Vaadin Forums: vaadin.com/forum/thread/17810577Janik
Yes, it is not supposed to be like that and it is causing some headaches, see github.com/vaadin/spring/issues/473Aliped

© 2022 - 2024 — McMap. All rights reserved.