0

I have the following route:

@Route(value = "jobs/:jobId", layout = JobsLayout.class)
@AnonymousAllowed
public class ViewJob extends VerticalLayout implements BeforeEnterObserver, HasUrlParameter<String> {

When I access the application by the following url:

/jobs/456/test

I correctly enters ViewJob view.

Now, I'd like to programmatically move to this view from another Vaadin view. For this, I'm trying to do the following:

UI.getCurrent().navigate(ViewJob.class, "456/test");

but the application fails with the following exception:

com.vaadin.flow.router.NotFoundException: No route found for the given navigation target 'com.example.ui.views.job.view.ViewJob' and parameters '{___url_parameter=456/test}'
    at com.vaadin.flow.router.RouteConfiguration.getUrl(RouteConfiguration.java:515)
    at com.vaadin.flow.component.UI.navigate(UI.java:914)

What am I doing wrong and how to correctly navigate to the ViewJob view?

UPDATED

The goal - I'm trying to implement the logic similar to StackOverflow - when you access the question page without a slug, for example Vaadin23 route navigation with parameters you will be automatically redirected to the correct url with slug added - Vaadin23 route navigation with parameters

For that I have the following view:

@Route(value = "jobs", layout = JobsLayout.class)
@AnonymousAllowed
public class AllJobsView extends VerticalLayout implements LocaleChangeObserver, HasUrlParameter<String> {

@Override
    public void setParameter(BeforeEvent event, @OptionalParameter String parameter) {
        try {
            Long jobId = Long.parseLong(parameter);
            Vacancy vacancy = vacancyService.findById(jobId, VaadinUtils.getCurrentLocaleIso6391());

            UI.getCurrent().navigate(ViewJob.class, new RouteParameters(Map.of(ViewJob.JOB_ID_PARAMETER, parameter, HasUrlParameterFormat.PARAMETER_NAME, vacancy.getNameSlug())));
            return;
        } catch (Exception e) {
            e.printStackTrace();
        }

This is ViewJob view:

@Route(value = "jobs/:jobId", layout = JobsLayout.class)
@AnonymousAllowed
public class ViewJob extends VerticalLayout implements BeforeEnterObserver, HasUrlParameter<String> {
....
}

When I try to access /jobs - AllJobsView is correctly rendered. When I try to access /jobs/507/vacancy5 - JobView is correctly rendered

but when I try to access /jobs/507 the following redirection logic is involed from AllJobsView.setParameter method:

UI.getCurrent().navigate(ViewJob.class, new RouteParameters(Map.of(ViewJob.JOB_ID_PARAMETER, parameter, HasUrlParameterFormat.PARAMETER_NAME, vacancy.getNameSlug())));

After that the user is correctly navigated to /jobs/507/vacancy5 url but the JobView content is not rendered.. only JobsLayout part.

What am I doing wrong?

alexanoid
  • 24,051
  • 54
  • 210
  • 410

1 Answers1

3

You have defined a route parameter in the url (:jobId). This has to match with the route parameter given to the URL:

UI.getCurrent().navigate(ViewJob.class, new RouteParameter("jobId", "456"));
Knoobie
  • 1,968
  • 10
  • 14
  • Thanks for your answer. I do the following now: `UI.getCurrent().navigate(ViewJob.class, new RouteParameters("jobId", "507"));` but it still fails with the: `java.lang.IllegalArgumentException: Navigation target 'com.example.ui.views.job.view.ViewJob' requires a parameter.` – alexanoid Aug 17 '22 at 11:28
  • This is expected, because combining Route Parameter with HasUrlParameter is not what you want. If you wanna access the jobId inside your class, you can use `BeforeEnterEvent` and call `event.getRouteParameters().get("jobId")`. – Knoobie Aug 17 '22 at 11:40
  • 1
    After Vaadin debug, I found that I have to add `HasUrlParameterFormat.PARAMETER_NAME, vacancy.getNameSlug()` to parameters. Now I'm able to redirect to ViewJob but ViewJob is not rendered correctly. I have updated my question with details. Could you please take a look? – alexanoid Aug 17 '22 at 12:57
  • Using `UI::navigate` inside the router lifecycle methods is discouraged, you could try `event::forwardTo` instead. – Knoobie Aug 17 '22 at 13:07
  • Thank you very much ! `event::forwardTo` did the trick ! – alexanoid Aug 17 '22 at 13:31