How to use URL parameters with router in Vaadin Fusion?

317 views Asked by At

I tried to follow the guide at Question, which results in a

mobx.esm.js?4fd9:2362 [mobx] Encountered an uncaught exception that was thrown by a reaction or observer component, in: 'Reaction[MainView.update()]' TypeError: Expected "item" to be a string

My configuration is

path: 'item/:item',
component: 'item-view',

Is there an example, how to solve this? Do I need to handle this in the MainView (I follow the todo-tutorial on vaadin.com?

2

There are 2 answers

0
Haprog On BEST ANSWER

The problem is that main-view.ts in the starter project has logic which tries to list all navigation routes to generate links for them. Currently that logic is not smart enough to detect and skip routes that have non-optional route parameters.

The error is thrown from router.urlForPath(viewRoute.path) when the path has non-optional route parameters because here we are not specifying what the value for the route parameter should be (for the generated URL). For generating a URL for the path 'item/:item' it would need to do something like router.urlForPath('item/:item', { item: 'my-item' }).

The quick fix (to remove the title from the route definition) suggested by Marcus works because the main-view.ts has logic to skip all routes that don't have a title. You could change that logic to also skip by some other criteria or you could try to include values for the route parameters there (for specific routes) if you really want to generate working navigation links for those routes.

Other alternative would be to mark the route parameter as optional (in case you want the route also to be accessible without a parameter) by adding a question mark after it, then the link can be generated without specifying a value for the parameter.

{
  path: 'item/:item?', // <- optional route parameter
  component: 'item-view',
  title: 'Hello World',
}
0
Marcus Hellberg On

It seems you have run into an issue with the starter. In main-view.ts, it loops over the routes with a title and tries to create a link for each in the menu:

${this.getMenuRoutes().map(
  (viewRoute) => html`
    <vaadin-tab>
      <a href="${router.urlForPath(viewRoute.path)}" tabindex="-1">${viewRoute.title}</a>
    </vaadin-tab>
  `
)}

However, router.urlForPath() breaks when there is a URL parameter definition instead of an actual parameter (items/:item instead of items/2).

A quick fix for this would be to remove the title property from your route configuration for any route that has a parameter.

{
  path: 'item/:item',
  component: 'item-view' 
  // make sure there is no title here
}