navigateToRoute - parameter object instead of by querystring

I was looking for an example of how to pass parameters using the router:
this.router.navigateToRoute(“myroute”, {value: 1});

but not have it show up in the URL as //localhost/myroute?value=1
and just have it passed to the activate method as a passed in object parameter.

The reason is I am passing some numbers and don’t want to have to parseInt() everything.

Now in the docs it says to use “settings” but I have added a settings property to a configured route with an empty object {}, and was hoping that when passing the second parameter to the navigateToRoute it would be added there, however it wasn’t.

Does anyone have a short example how to do that correctly as I have apparently failed miserably?

You can have settings on a route yes, but the common way they are suggested is a setting on the route config, your activate() method within your child view has additional params to access those. The second param ‘config’ has the route definition along with the route config settings you can add onto it.

activate(params, config, navInstruction)

You can’t really navigateToRoute with hidden params, urls don’t really work that way, the router tries to maintain state with the url.

You can have settings sitting off in a singleton object that you can import wherever however, when your child view is attached you can read them off or subscribe to them in the case of rxjs or the aurelia binding engine.

Singleton Class

export class MySingleton {

   someSetting: 'foo'

   constructor() {
      // this object is only created once, so this is only called once
   }

}

Consuming Component/View

import { inject } from 'aurelia-framework';

import { MySingleton } from './file/location/here';

@inject(MySingleton)
export class SomeView {
   constructor(mySingleton) {
      this.mySingleton = mySingleton;

      console.log(this.mySingleton.someSetting);
   }
}

If you need this setting to be tied to router navigation (forward/back buttons) as in the router knows the settings’ state before nav and after rather then just what it currently is then it’ll have to be in the url, otherwise it’ll be using whatever the js object has.

Thanks for the review and time to do so.

My application is that I have two paths to the route.
One route is the logged in users normal navigation to the page to view some data.
The other route is an admin that uses the same page, but instead of loading based on the logged in user, it uses the passed parameter to display the data for the member selected (passed in params).

I was trying to keep the url clean, and I don’t want that to be bookmarkable with the parameters in the url. I guess I will have to reexamine what I am doing, and perhaps use the Aurelia Store to set that override.

The router is designed to map urls to sections of the view. The chief method for communicating with the router is through the url.

I don’t want that to be bookmarkable with the parameters in the url.

So, if that is the case, you’re not going to want to use the router to handle this, as this describes what the router does.

Now in the docs it says to use “settings” but I have added a settings property to a configured route with an empty object {}, and was hoping that when passing the second parameter to the navigateToRoute it would be added there, however it wasn’t.

If you don’t mind creating a second route that has extra configuration data, this is the right way to go. See this example: https://gist.run/?id=58b942df748490b5cac8bdf1e4ebc18e. On load you’ll see the extra data. If you navigate to “a”, you’ll see the same view without the extra data.

The other route is an admin that uses the same page, but instead of loading based on the logged in user, it uses the passed parameter to display the data for the member selected (passed in params).

Router is a fine way to approach this. If you want to get a bit more technical for keeping the URL clean and not bookmarkable, create and inject a service that keeps track of the currently visible user.

export class UserService {
  
  currentUser = null;

  changeUser(userId) {
    this.currentUser = userId;
  }

  getCurrentUser() {
    return this.currentUser;
  }
}

You can use this service to track the currently spoofed user in memory, as well as to handle other important functions like checking if the currently logged in user has permission to spoof other users. Finally, you can use this pattern to implement more advanced features such as session storage to keep track of the currently logged in user on refresh, if desired.

Thanks for taking the time to put that together.

I have ended up using the second method, and just setting the current admin selected memberId to the Aurelia Store State.

In most cases its not an issue as the state boilerplate is already being used in the viewmodel, but some don’t intrinsically need it and it just adds noise compared to if there was the ability to pass the parameters with the routers navigate methods and capture that in the activate method [as I currently understand how to use it]

I could do a mix of both methods, but then thing get muddied and I think become a maintenance nightmare over time. So for now using the store is my method of choice.

BTW, enjoy your blog posts on Aurelia

Glad you got things worked out, and I appreciate the complement. More posts coming soon.