balazska
balazska

Reputation: 971

Aurelia - Dynamic redirect in a child route

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.

Upvotes: 3

Views: 1071

Answers (1)

balazska
balazska

Reputation: 971

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.

Upvotes: 4

Related Questions