Reading data from databas onAttach or afterNavigation?

Hi!

I’m looking for best practices for loading data from external sources, such as a database (e.g. via JPA).

Would you recommend fetching the data in onAttach() or afterNavigation()?

If you don’t have a reason not to do so, I would recommend afterNavigation as it’s based on a higher level concept. If you look at the JavaDocs, it’s more immediately obvious when an afterNavigation event occurs - “after all navigation tasks have resolved.”. onAttach happens “when the component is attached to a UI.”; you still need to understand when a component might be attached to a UI, and what is a UI in the first place…

2 Likes

It also depends on how you keep and present your data. For instance, in a grid with a lazy loading data provider, you do not have to take care of the “when”, but only the “how”.

For in memory, also, the amount of data might be a factor and when the component will be shown. For instance, a component that is only shown sometimes and only after some time, does not necessarily have to load the data on navigation time.

So there is no simple answer in general but better to know the specific use cases

1 Like

Thank you for your answers!

I feel that maybe Vaadin could be a bit more opinionated there - sometimes. It’s an age old discussion when to best do the “things” that you need to do in order to get the page displayed properly with all its data loaded / translated etc.

  • constructor (yes)
  • onAttach()
  • afterNavigation()
  • setParameter()

It can be a bit overwhelming, and there are consequences to each approach.

1 Like

Mostly, I load my data on the beforeEnter event. I prefer using Route Templates instead of the HasUrlParameter interface.

In this beforeEnter stage (at least for my application designs):

  • The view layout is ready
  • I can check for parameters and access
  • You can forward when an error occurs or data is not found

When you are want to react to url parameters, the contructor (and onAttach ?) are maybe too early for a parameter being set.

**Use the new placeholder for the grid. On attach show the placeholder element, then pull data from database async. Then update the grid afterwards **

I would not generally recommend beforeEnter as the purpose of beforeEnter is to perform what ever checking that is needed before view can be entered, e.g. access control, possible re-routing etc. Thus accessing backend is typically pre-mature at this stage. That is why afterNavigation is more correct as at that stage it is clear that user had authority access this view, the view is no longer going to be renavigated etc.

1 Like

While I agree with Tatu, I would like to add: sanity checks like “is the given URI Parameter really in my database and can be accessed by the current user” can also fall in the category of “okay to be done here” - even tho they can contain DB queries

Maybe @Petter has an opinion about it.

In general ( it’s always hard to give a general advice that will always work), I’m not retrieving data in the constructor. I prefer to do it after navigation since I prefer to do it after everything. ( Security access)

This is how I do it:

  • If I use a lazy-loading data provider, I set it up in the constructor together with the rest of the UI.
  • If I’m inside a view that receives navigation events, I load the data in afterNavigation (unless I have a good reason to do it earlier, like the validation case suggested by @knoobie).
  • If I’m inside a self-contained custom component that does not receive navigation events, but will be added to a view, I load the data in onAttach.

There are other things to consider as well. If you use a pattern that has a model that your user interface is observing (like MVVM), or at least reading data from, then you’d set up the model in the constructor. If components can observe the model (meaning they will get notified when the model changes), you’d register the listeners in onAttach and remove them in onDetach. Finally, you’d populate the model with data in afterNavigation.

5 Likes