1

I am curious: Is there a possibility to change the URL query parameters when navigating from one view to another in a generical fashion?

What's my use case? I would like to append a query parameter "referrer" to the URL when navigating from view A to view C. This should also be done when navigating from view B to C. Once view C is open, there is some action that should return to the previous view. This "previous view" information could then be determined by "referrer" URL query parameter. For concrete example this is already working.

Moreover, I would like to generify the behavior with some annotations on view classes. E.g. view A and B are annotated with my @ReferrerSource and view C with my @ReferrerTarget annotation. So every time when navigation takes place in my application I would like to consider these view annotations and add the "referrer" URL query parameter on demand.

Is this even possible?

Steffen Harbich
  • 2,639
  • 2
  • 37
  • 71
  • Have you tried with https://vaadin.com/docs/v14/flow/routing/tutorial-routing-lifecycle.html#beforeleaveevent ? Yet this sounds a lot like browser-back or history api the convoluted way? – cfrick Feb 04 '20 at 14:02
  • Yes I tried the navigation events but they do not provide the possibility to change the URL query parameters while navigating, as far as I see. Browser back could work but that feels odd: Consider view C to be an edit view and the action a "save". The "save" would persist the object and move back in browser history. A "forward" navigation in browser history would return to edit view. Feels unusual. – Steffen Harbich Feb 05 '20 at 07:47

1 Answers1

1

Referrer Source View:
when navigating away from the view, you could do so with the method UI.getCurrent().navigate(String location, QueryParameters queryParameters).
Or if you use RouterLink for navigation, you can set query parameters there too: routerLink.setQueryParameters(QueryParameters queryParameters).

This is not something that could be done via annotation or interface, as it cannot be done in any kind of navigation Observer. Optimally you should be able to add the referrer queryParameter to the BeforeLeaveEvent, but I don't think you can do that yet (you can get the QueryParameters from it but you cannot edit them there).


Referrer Target View:
You can read the url parameters from the beforeEnterEvent or the afterNavigationEvent in referrer target view. The referrer value you can store in a field of the view, and use it when the user presses your "previous view" button. I'm not sure how you could do it via annotation, but it should be doable with an interface if you want to.

@Override
public void afterNavigation(AfterNavigationEvent event) {
    Map<String, List<String>> parameters = afterNavigationEvent.getLocation().getQueryParameters().getParameters();
    // TODO: check parameters for your referrer parameter, and save it in the view
}

Another possible solution would be to leave the QueryParameters alone, and save the previous view in the UI scope (just like you advised recently in one of your own answers ;P). Now, as of Vaadin 14 I'm genuinely not sure how this works, as the UI instance is rebuilt upon navigation. But I'm sure there is a good solution, there is much discussion to find about this topic on SO, vaadin forums, and vaadin github.

kscherrer
  • 5,486
  • 2
  • 19
  • 59
  • Agreed. These are the options to solve my problem. To combine your ideas with annotation-based approach I made my own navigation helper class that has two methods: first is for navigation from referrer to target (inspects `@ReferrerSource` annotation on referrer view class) and second is for navigation from target back to referrer (inspects `@ReferrerTarget` annotation on target view class). Thanks for your answer. – Steffen Harbich Feb 06 '20 at 14:13
  • Regarding the UI scope: As far as I know, UI instance is only rebuilt when navigation is not done via `RouterLink`, `UI.getCurrent().navigate` method or browser history. Other navigations like hitting F5 (when @PreserveOnRefresh is not set) in browser, usual links or invoking the URL directly in browser will trigger a new UI instance. – Steffen Harbich Feb 06 '20 at 14:16
  • 1
    related: https://github.com/vaadin/flow/issues/8712 apperantly this changes with vaadin 17 – thi gg Jul 20 '20 at 15:03