DevMike
DevMike

Reputation: 1821

In Angular, what is the correct way to implement a route with an optional parameter without having to define a second route?

As to the suggestion that this question has already been answered, that answer suggests a workaround solution that does not solve my use case.

My route has 2 parameters, one being optional. It is a lazy loaded route, but I assume this should not matter as it relates to my question. If it does matter please let me know.

The route:

{ path: 'list/:name/:type', loadChildren: './list/list.module#ListModule'},

The :name parameter is required for this route to load correctly, but the :type parameter is optional.

I tried defining 2 separate routes and setting both to point to the same component, one with the parameter and one without, but this is not a working solution in my case.

I'd like the browser's history to be correct and reflect the addition of, or update to the optional :type parameter via user interaction without requiring navigation to another route causing the component to reload.

So, it is the initial route entry that is the problem. Once the :type parameter has been defined the first time, subsequent changes would not require a route change.

I'd like to ask, specifically, is it possible to define an optional parameter for a route in Angular?

Or, as a solution to this problem, is it possible to update the route / URL after the route has instantiated without triggering navigation?

Upvotes: 1

Views: 1379

Answers (1)

DevMike
DevMike

Reputation: 1821

As it turns out Angular does actually offer a way to use optional parameters.

Although this still does not solve the fact that the initial instantiation without the parameter present will still require navigation to arrive at the same route with the parameter present. I was trying to avoid triggering a reload in the browser.

Thank you @johnsharpe for pointing this out i do not know how i missed it. It's intended use solves situations that require more complex url structures, but this is the correct answer.

Angular docs on optional params

After a lot of digging around, i also came across this video Angular Tutorial on Parameterized Routes which actually covers my use case, how to define an optional parameter in Angular, and why you might need to use one in-order to maintain functional browser navigation. The answer that Veselin Davidov referenced above creates a problematic browser history. How? The reason is explained approximately 11 minutes into the video.

To implement a route parameter as optional, you first define a route without the optional parameter present. Using my case as an example, i define my route with the required :name parameter only:

{ path: 'list/:name', loadChildren: './list/list.module#ListModule'},

And then when navigating to this route from within my application, i can define the optional :type parameter like so using an object with key/value pairs:

this.router.navigate['list', name, {type:value}];

instead of this:

this.router.navigate['list', name, type];

This approach uses matrix url notation. The resulting url has a semicolon and looks like this:

mysite.com/list;type=value

When sharing and/or reloading this resulting url, Angular will pick up the matrix parameter and make it accessible as a route parameter.

Ironically though, using a matrix parameter has other implications and as such this might not be an advisable approach. See this question/answer for more detail.

So, you might be thinking, as i did, then whats the difference? why not just use a query string parameter instead? see this on differences between matrix and query

Upvotes: 3

Related Questions