AppLayout as annotation and HasUrlParameter

Hi,

I have a view as entrypoint of my application which navigates to the first view with a parameter:

@Route("")
public class ViewStart extends VerticalLayout {
    public ViewStart() {
	    super();
	    add(new Button("Start", e -> getUi().ifPresent(ui -> ui.navigateTo(View1.class, "foobar"))));
	}
}

There are two views with HasUrlParameter:

@Route("view1", layout = MyLayout.class)
public class View1 extends VerticalLayout implements HasUrlParameter<String> {
    @Override
    public void setParameter(BeforeEvent be, @OptionalParameter String param) {
        Notification.show(param);
    }
}
@Route("view2", layout = MyLayout.class)
public class View2 extends VerticalLayout implements HasUrlParameter<String> {
    @Override
    public void setParameter(BeforeEvent be, @OptionalParameter String param) {
        Notification.show(param);
    }
}

And the layout which is only used by my views has have a parameter:

public class MyLayout extends AppLayout {
    public MyLayout() {
	    super();
		Tabs menu = createMenu();
		addToNavbar(true, menu);
	}
	
	private Tabs createMenu() {
	    String param = retrieveParam();
		
		Tabs tabs = new Tabs();
		Tab tab1 = new Tab(new RouterLink("View1", View1.class, param));
		Tab tab2 = new Tab(new RouterLink("View2", View2.class, param));
		return tabs;
	}
	
	private String retrieveParam() {
	    // How do i retrieve the url-param in the layout to use it in the navbar?
	}
}

My problem is the retrieveParam() method in the layout:

  • the layout doesn’t know anything about the HasUrlParameter of its views
  • if I remember correctly I didn’t have access to the current request during instantiation
  • the navbar has to be created during instantion
  • the href in the RouterLink can’t be easily replaced with a new class-target and parameter after initial creation

I tried some solutions with VaadinServletRequest req = (VaadinServletRequest) VaadinService.getCurrentRequest();, etc but it feels quite unstable.
I don’t want to store the value in the session since i want to provide direct access via url to the view with .../view1/my-param.

How can I resolve this and respect the current parameter of the view in the navbar of its layout?

To clarify:
((VaadinServletRequest) VaadinRequest.getCurrent()).getRequestURI() seemed like the best idea, but on the initial request to e.g. enter View1 it still contains the URI of the StartView.

My current working solution is implementing BeforeEnterObserver to my layout.
There i grab the parameter from the segments of event.location().getSubLocation() and creating the navbar after that instead of using the constructor.

Maybe someone has a better solution but I guess this might work for now.