router: Incorrect routing when using navigationStrategy callback

Currently, I’m looking into dynamic routing in aurelia. To achieve this, I mapped all routes using a wildcard and I’m using the navigationStrategy property to determine the correct module id (as suggested in https://github.com/aurelia/router/issues/129).

configureRouter(config: RouterConfiguration, router: Router): void {
    config.map([
        { route: "**", nav: false, navigationStrategy: this.navigateToModule, settings: this }
    ]);

    router.handleUnknownRoutes(this.unknownRoutes);
}

private navigateToModule(instruction: NavigationInstruction): void {

// some logic to determine a moduleId
instruction.config.moduleId = moduleId; // A valid view-model
}

The first navigation is correct and loads the correct viewmodel, as expected. However, when I now navigate to another route in the same Router (with another moduleId), it always navigates to the current active viewmodel (instead of the new one). The navigationStrategy callback is called witch each navigation, as expected.

The activate() function of the current (incorrect) viewmodel is called, while the navigationInstruction.config.moduleId in the activate() function contains the new moduleId (as set in the navigateToModule function). When refreshing the site, the correct viewmodel is loaded.

The code is running on the current Aurelia release (beta.1.1.0), using Typescript. I’m encountering this in all browsers. Is this expected behavior?

I also tried to map the routes using the handleUnknownRoutes (as sugested in https://github.com/aurelia/router/issues/15). This is working as expected. However, I prefer to use the described way, since it is possible to use to settings property in the router better (there is no reference to the original class in the handleUnknownRoutes callback) and it is possible to use multiple wildcards and redirect them to other functions.

About this issue

  • Original URL
  • State: open
  • Created 8 years ago
  • Reactions: 1
  • Comments: 15 (9 by maintainers)

Most upvoted comments

@EisenbergEffect @davismj We’re seeing this too, and it’s definitely a bug.

Basically, we have a route, /flights/:destination, with a navigation strategy, which sets navigationInstruction.config.moduleId dynamically based on the type of place referenced by the destination parameter in the URL.

This works correctly on the first navigation to that route. However, if you then, while on that route, try to navigate to the same route, but with a place of a different type, things break. The navigation strategy is correctly executed, and a new moduleId is assigned to the navigation instruction config, but as illustrated in the screenshot below, it still ends up reusing the previous viewport instruction, and thus breaks things.

For example, on the line with the breakpoint, it fails to realize that the moduleId was changed, which means it doesn’t set the activation strategy to replace, and therefore never actually loads the new module - as you can see in the watches at the top-right, the new moduleId is in fact assigned to config, but nextViewPortConfig still has the old value.

image

Ok, so I managed to make it work, in a way. The first time navigationStrategy is called navigationInstruction.config does not have viewPorts set. On subsequent calls viewPorts is set and its moduleId is set to the moduleId from the first call. So viewPorts.default.moduleId also has to be set to the moduleId we want. If this is how it should work, it has to be added to the docs about Dynamically Specify Route Components.