Route parameters
A route parameter is a changing part of the address. To open post number 5 for editing, an address like /posts/5 is handy: you can bookmark it and send it to a colleague. Vaadin takes the parameter from the address, converts it to the right type and passes it to the view before the view appears on the page.
HasUrlParameter
Let us make the form from the data chapter able to both create and edit:
// src/main/java/com/example/blog/views/PostFormView.java (changed parts)
@Route("posts")
@PageTitle("Post")
public class PostFormView extends VerticalLayout implements HasUrlParameter<Long> {
private final H2 heading = new H2();
private Post post;
@Override
public void setParameter(BeforeEvent event, @OptionalParameter Long id) {
if (id == null) {
post = new Post();
post.setPublishedOn(LocalDate.now());
heading.setText("New post");
} else {
post = service.findById(id).orElse(null);
if (post == null) {
event.forwardTo(PostListView.class);
return;
}
heading.setText("Edit post");
}
binder.readBean(post);
}
}Put heading first in the constructor's add(...), and keep the service in a service field. Imports from com.vaadin.flow.router: HasUrlParameter, BeforeEvent, OptionalParameter; plus com.vaadin.flow.component.html.H2.
| Address | What opens |
|---|---|
/posts | An empty "New post" form, id is null |
/posts/1 | The form with the post "Hello, Vaadin" |
/posts/999 | No such post — redirect to the list |
/posts/abc | Not a number — the "Could not navigate to 'posts/abc'" page |
setParameter runs on every navigation to the view, before the view is shown. @OptionalParameter allows the address without a parameter.
Navigating with a parameter
In the grid, let us open a post on double click:
// src/main/java/com/example/blog/views/PostListView.java (part of the constructor)
grid.addItemDoubleClickListener(event ->
getUI().ifPresent(ui -> ui.navigate(PostFormView.class, event.getItem().getId())));A double click on the "Grids and forms" row opens /posts/2 with a filled form. The second argument of navigate is the parameter value; Vaadin puts it into the address.
Route templates
When there are several parameters or they sit in the middle of the address, use a template. Parameter names start with a colon:
// src/main/java/com/example/blog/views/CommentsView.java
package com.example.blog.views;
import com.vaadin.flow.component.html.H2;
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
import com.vaadin.flow.router.BeforeEnterEvent;
import com.vaadin.flow.router.BeforeEnterObserver;
import com.vaadin.flow.router.Route;
@Route("posts/:postId/comments")
public class CommentsView extends VerticalLayout implements BeforeEnterObserver {
private final H2 heading = new H2();
public CommentsView() {
add(heading);
}
@Override
public void beforeEnter(BeforeEnterEvent event) {
long postId = event.getRouteParameters().getLong("postId").orElseThrow();
heading.setText("Comments on post " + postId);
}
}The address /posts/2/comments shows "Comments on post 2". A template can restrict a parameter with a regular expression: :postId([0-9]+).
Query parameters
The part of the address after ? is read like this:
// src/main/java/com/example/blog/views/CommentsView.java (part of beforeEnter)
String sort = event.getLocation().getQueryParameters()
.getSingleParameter("sort").orElse("new");For /posts/2/comments?sort=old the sort variable is old, without the parameter it is new.
Common mistake
The parameter is declared without @OptionalParameter, and the "New post" button navigates without it:
// src/main/java/com/example/blog/views/PostListView.java (fails without @OptionalParameter)
ui.navigate(PostFormView.class);The click ends with an exception:
java.lang.IllegalArgumentException: Navigation target 'com.example.blog.views.PostFormView' requires a parameter.Mark the parameter with @OptionalParameter or pass the value as the second argument of navigate.