3

I have an Aurelia app, the parent and child router. Parent:

{ name: 'group', route: 'group/:groupId', viewPorts: {
    Filter: { moduleId: 'filter.js'},
    Content: { moduleId: 'content.js' }
}}

The child router is set up:

[
    { name: 'home',      route: ''          },
    { name: 'documents', route: 'documents' },
    { name: 'images',    route: 'images'    },
    { name: 'specs',     route: 'specs'     }
]

The child router is configured in content.js. I'd like to achieve, that in the parent router, I navigate without having specified the childs full path

router.navigateToRoute('group', { groupId: 12345 });

In the child router, this will end up in home, where I'd perform a dynamic redirect based on some app state. How should it be achieved? So far, I've tried these

With RedirectToRoute:

activate(params: any, config: any, instruction: NavigationInstruction): any {
    return new RedirectToRoute('pick one child route');
}

Inject Router:

@inject(Router)
export class Home {
    constructor(router: Router) {
        this.router = router;
    }
    activate(params: any, config: any, instruction: NavigationInstruction): void {
        this.router.navigateToRoute('pick one child route');
    }
}

The redirect/navigation itself is correct locally, however, the baseUrl of the (child) router still points to the old (parent) route, so the result will be incorrect.

For example: we are on a page of: group/98765/images and in the parent router, we navigate: router.navigateToRoute('group', { groupId: 12345 });. As expected, we'll end up group/12345 and home's activate method will be fired.

We redirect here, let's say to specs. But instead of group/12345/specs, we'll end up in group/98765/specs, due to outdated baseUrl.

How should it be fixed?

I've seen some related issues with child router's baseUrl, the suggestion was to fix manually to a constant, before navigating. However, due to templated routes (which are more complex, than shown in this example), this is not as easy as just setting the baseUrl to a constant string.

2

1 Answer 1

4

Although router events would work, but it is not elegant, since two navigation will occour and will appear in the browser history. If the user tries to navigate back, he/she cannot, because navigates back to home route, which'll immediately navigate forward to the selected child route.

The "right" way (in Aurelia documentation): use navigationStrategy callback when configuring the router. So this is how to set up the child router:

configureRouter(config: RouterConfiguration, router: Router) {
    const navStrat = (instruction: NavigationInstruction) => {
        instruction.config.redirect = 'pick one child route';
    };
    config.map([
        { name: 'redirecter', route: '',         navigationStrategy: navStrat },
        { name: 'documents',  route: 'documents'                              },
        { name: 'images',     route: 'images'                                 },
        { name: 'specs',      route: 'specs'                                  }    
    ]);
}

This will result in one navigation cycle, and one can implement any dynamic redirect logic.

1
  • 2
    Mind, that AppRouter (the top-level router) sends EventAggrerator events, such as 'router:navigation:success'. This is just not the best solution
    – balazska
    Commented Feb 14, 2017 at 9:28

Not the answer you're looking for? Browse other questions tagged or ask your own question.