Router-lite: navigate to optional param within same route

Let’s say we have an active route, e.g. ‘route-1’.

getRouteConfig() {
  return {
    routes: [
      { route: 'route-1', component: Component1 }
    ]
  };
}
  1. In Au1 it was possible to navigate within the same route:

    this.router.navigateToRoute('route-1', { optionalParam: 'xy' })

    This updates the url to /route-1?optionalParam=xy

  2. Furthermore, it was possible to extend it like

    this.router.navigateToRoute('route-1', { optionalParam: 'xy' }, { trigger: false })

    This also updates the url to /route-1?optionalParam=xy, but does not reload the page / execute the lifecycle hooks.

Are these 2 concepts somehow possible in router-lite / Au2?

Thanks for any help.

UPDATE
Just had some partial success: routing within same route - StackBlitz

this.router.load('../product', { queryParams: { id: 'product-1' } });

and

loading(params, next: RouteNode) {
  this.id = next?.queryParams.get('id');
}

Is this the correct way? Is it possible to force a refresh of the lifecycle hooks / a refresh of the route? Currently it only updates the url.

Thanks @elitastic for reporting this.

Seems like a missing feature. I can add the feature in coming days. It might look something like below.

this.router.load(
  { component: Product, params: { id: 'product-1' } },  // <- this works already
  { transitionPlan: 'replace' | 'invoke-lifecycle' }
);

However, it might take some time, as there are already some ongoing work.

Thanks for the feedback @Sayan751. I am still a bit confused about how routing works in Aurelia 2 (router-lite).

  1. Is it possible to navigate by queryParams in load custom attribute?

    <a load="route: ../product; queryParams.bind: { id: 'product-1' }">Navigate</a> // not working

    vs

    this.router.load('../product', { queryParams: { id: 'product-1' } }) // working

  2. In general, how is the route id differentiated from the routing path?

    <a load="route: xy">Navigate</a>

    Is xy a route id or a route path? Could it be both?

  3. Shouldn’t it be possible to route by params in router.load() (like it is in the load custom attribute)?

    this.router.load('product', { params: { id: 'product-1' } }

  4. Is it possible to route to a route id combined with passing a route context? E.g.:

    <a load="route: product; params.bind: { id: 'product-1' }; context: routeContext.parent">Navigate</a>

    or even

    <a load="route: ../product; params.bind: { id: 'product-1' }">Navigate</a>

    Couldn’t get it work, please see repro: routing by route and param - StackBlitz

Thanks for any help!

Hi @elitastic! Sorry for the delayed reply. I would primarily point you to the relevant docs for this: https://docs.aurelia.io/router-lite/navigating. The docs should sufficiently cover this topic.

Now to answer your individual questions…

  1. Is it possible to navigate by queryParams in load custom attribute?

No. The load attribute does not support binding query parameters. Please refer to the docs, for the supported properties of the load CA.

  1. In general, how is the route id differentiated from the routing path?

From the docs:

The unique ID for this route. The router-lite implicitly generates a id for a given route, if an explicit value for this property is missing. … this can be used to generate the href s in the view when using the load custom attribute or using the Router#load API. Using this property is also very convenient when there are multiple aliases for a single route, and we need a unique way to refer to this route.

Is xy a route id or a route path? Could it be both?

Yes, it could be both. Sometimes, the lookup using the route-ids is often prioritized internally over recognizing a path. However, as the route property is polymorphic, you are free to choose among route-id, path, or a route view-model class.

  1. Shouldn’t it be possible to route by params in router.load() (like it is in the load custom attribute)?

It is already possible. Instead of,

this.router.load('product', { params: { id: 'product-1' } }

you need to do this

this.router.load({ component: 'product', params: {id: 'product-1' } })

Check out this working example: router-lite - IRouter#load - string-instructions - StackBlitz.

  1. Is it possible to route to a route id combined with passing a route context?

Yes, it is possible. Refer to the docs: https://docs.aurelia.io/router-lite/navigating#customize-the-routing-context. However, it works only if the route-id is used. Thus, the following from your example won’t work.

<a load="route: ../product; params.bind: { id: 'product-1' }">Navigate</a>

The assumption is that if you are binding a path, then you can also add the parameters. Using a path and the parameters at the same time can be semantically confusing, IMO. In your example, you have done something like below.

    this.router.load('product-path', {
      queryParams: { id: 'product-1' },
      context: this.routeContext.parent,
    });

This is also incorrect, as you are trying to add the route (path) parameters to the query.

Many thanks for your help.

Some things seems still a bit confusing for me, e.g. providing a route id to a property called component looks very generic for me: this.router.load({ component: 'route-id', params: {id: 'param1' } })

Furthermore, mixing params and queryParams in combination with routing context is quite complex and was a lot easier in Aurelia 1 in my opinion:

Au2

this.router.load(
{
  component: 'route-id',
  params: { id: 'param1' }
},
{
  context: this.routeContext.parent,
  queryParams: { optionalParam: 'test123' },
}
);

vs Au1

this.router.navigateToRoute('route-id', { id: 'param1', optionalParam: 'test123' });

I think I will try to write my own custom attribute to handle my needs, that’s fine for me. Thanks for your help anyway.

Note that you can add any number of unconfigured parameters while using load in the params object. Those will be automatically added to the query string.

This is because we are trying to keep the API polymorphic. If there were a separate load method for every supported overload, it might not be very user-friendly IMO. Do you have an alternative in mind?

That’s great, I didn’t know that!

OK, I understand your polymorphic approach. I just did not expect that the component property can be passed a route id because of the property name component. It rather reminds me of the direct routing from aurelia-direct-router (route to component).

But it’s fine for me, I now understand the point of the component prop.

1 Like