1
votes

When the user first launches my Aurelia web app, I need to check localStorage to see if my app needs to restore its last state. If it does, it needs to set internal model values from localStorage and restore the route. If not, it just needs to set the route to the initial route (called 'game'). So I figured I could set up my router config in app.js like this:

config.map([
    { route: '', name: 'launcher', moduleId: 'launcher'},
    { route: 'game', name: 'game', moduleId: 'game-view'},
    ......

Where the launcher module will do this initialization.

launcher.js (partial pseudocode):

import {
    inject,
    noView
} from "aurelia-framework";
import {
    Router
} from 'aurelia-router';

@noView
@inject(Router)
export class Launcher {
    constructor(router) {
        Get localStorage values, including lastState;

        if (need to restore the past state) {
            router.navigateToRoute(lastState);
        } else {
            router.navigateToRoute('game');
        }
    }
}

The issue is, I really don't need a view for this module, but if I don't have a launcher.html file, Aurelia throws an error (even though everything works okay). I figured the noView decorator would do the trick, but it didn't.

Is there a way to have a navigable module without a view? Is there a better way to do this?

3
I wouldn't use a view-model for this logic it doesn't make any sense. You can do this in a router hook or even in your app.js you can call a service which does this for you.PW Kad
@PWKad Yeah. Didn't seem like a good way to do this. I tried calling router.navigateToRoute in my app.js, but it didn't work. Maybe I was calling it at the wrong time. I haven't used router hooks. Can you point to info on these?Jeff G
@PWKad I suppose I could change the route in config.map to ['', 'game'], and then add canActivate to my game view-model. If there is no saved state, I would just return true. If there is, I would suppose I would return a navigation command (per the docs). Then my question is what is a navigation command?Jeff G
Check out pipelines. You might be able to use that.Robinson Collado
@RobinsonCollado I'll check them out.Jeff G

3 Answers

4
votes

You can also use the @noView attribute if you do not want a view.

basic usage:

import {noView} from 'aurelia-framework';

@noView
export class MyClass{
}
2
votes

you could inject the Launcher into your app.js:

import {inject} from 'aurelia-framework';
import {launcher} from '[file path to launcher]';

@inject(launcher)
export class App{
    constructor(launcher)
    {
        this.launcher = launcher;
        this.launcher.activate();
    }
}

then in your launcher activate method, have your logic:

import {inject} from "aurelia-framework";
import {Router} from 'aurelia-router';

@inject(Router)
export class Launcher {
    constructor(router) { 
        this.router = router;
    }

    activate(){
         Get localStorage values, including lastState;

         if (need to restore the past state) {
             this.router.navigateToRoute(lastState);
         } 
         else {
             this.router.navigateToRoute('game');
         }
    }        
}

if that doesn't work, then another option is to set the root then navigate to a certain state, i.e.

import {inject, Aurelia} from 'aurelia-framework';

@inject(Aurelia)
export class Launcher{
    constructor(Aurelia){
        this.aurelia = Aurelia;
    }

    activate(){
        Get localStorage values, including lastState;

        if (need to restore the past state) {
         this.aurelia.setRoot([file path of starting page])
             .then((aurelia) => {   aurelia.root.viewModel.router.navigateToRoute('lastState');}); 
     } 
     else {
         this.aurelia.setRoot([file path of starting page])
             .then((aurelia) => {  aurelia.root.viewModel.router.navigateToRoute('game');}); 
          }
     }

}

just make sure your starting page, which will have the router map, isn't app.js because then you'll have a circular dependency. You can make another file to be your starting page.

0
votes
constructor(router) {
    this._router = router;
}

activate(){
    //Get localStorage values, including lastState;
    if (need to restore the past state) {
        this._router.navigateToRoute(lastState);
    } else {
        this._router.navigateToRoute('game');
    }
}