Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Lazy loaded module's resolver is not being kept as singleton #13722

Closed
jbridger opened this issue Dec 30, 2016 · 6 comments
Closed

Lazy loaded module's resolver is not being kept as singleton #13722

jbridger opened this issue Dec 30, 2016 · 6 comments
Labels
area: core Issues related to the framework runtime area: router

Comments

@jbridger
Copy link

I'm submitting a ...

[x] bug report => search github for a similar issue or PR before submitting
[ ] feature request
[ ] support request => Please do not submit support request here, instead see https://github.com/angular/angular/blob/master/CONTRIBUTING.md#question

Current behavior
What we're trying to achieve:

  • We have implemented a resolve guard in a lazily loaded module that will navigate to an error component on failure to retrieve data.
  • The resolve guard will also store the failure message in a field of itself.
  • The error component takes the resolve guard as a dependency, and displays the error message from it.

Our implementation is very similar to the Tour of Heroes example with the resolve guard navigating to another page on failure. See this plunkr example, and click on any crisis under the Crisis Center

We have produced an example of the problem by extending the Tour of Heroes example.

When CrisisCenterModule is lazily loaded, we have observed:

  • The resolver instance for CrisisDetailComponent is different to the instance being injected in to ErrorComponent, which is a sibling route to the activate route. We have confirmed that the resolver is only provided inside the CrisisCenterRoutingModule, which is inside the lazily loaded module.
  • We can see that the CrisisCenterModule and all it's contained modules and components are instantiated twice, with different injectors.

When CrisisCenterModule module is not lazily loaded, this problem does not occur.

This was previously working when we were using Angular 2.1.0, until we upgraded to 2.3.1/2.4.1. We narrowed it down to when the version of @angular/router changed from 3.1.0 to 3.2.0. This problem did not occur with the beta and RC versions of 3.2.0.

We did consider using an intermediate service for the resolver to share the error message to another component, but we experienced the same issue with multiple instances of this service.

Expected behavior
Clicking on a crisis under the Crisis Center in this plunkr example, you will see Error component - error message:, whereas we expect to see Error component - error message: error.

We created another plunkr example where CrisisCenterModule module is not lazily loaded, and the problem does not occur.

Minimal reproduction of the problem with instructions
We have modified Tour of Heroes example in the following ways:

  • app/crisis-center/crisis-detail-resolver.service.ts - Modified to always set the errorMessage field, and navigate to the ErrorComponent.
  • app/crisis-center/error.component.ts- Newly added. Displays the errorMessage field from the injected CrisisDetailResolver.

You can download this example Github project where the @angular/router version is 3.2.0. To run:

  • npm install
  • npm run
  • Open http://localhost:4200
  • Click on a crisis under the Crisis Center
  • You will see Error component - This is the error message:, which is missing the error message from the resolver.
  • You can see in the console log that the CrisisCenterModule is instantiated twice with different injectors, and the error message is not displayed.

To see it working, you must switch the version of @angular/router to 3.1.0 in packages.json, clear the npm_modules folder, and re-run the above steps. You should see the following displayed: Error component - This is the error message:I failed to load crisis. You will also see in the console log that components are only being initialised once.

Alternatively, you can reproduce with this plunkr example.

What is the motivation / use case for changing the behavior?
We want the resolver to handle failure to load data and navigate to a component that can handle this failure appropriately. This seems to be the pattern that is shown in the Tour of Heroes example (from the Routing advanced guide).

The alternative would be to modify the resolver to wrap failures in a result object, and let the activated route component handle success and failure cases. We'd like to avoid this, as it would make the component more complex.

Please tell us about your environment:

  • Mac OS X 10.11.5

  • Angular version: 2.4.1. @angular/router at 3.4.1. Works when router is at 3.1.0.

  • Browser: Chrome 55.0.2883.95

  • Language: TypeScript 2.0.3

  • Node (for AoT issues): node --version = 6.2.1

@jbridger jbridger changed the title Lazy loaded module's resolve guard injector is not using module's injector Lazy loaded module's resolve guard is not kept as singleton Dec 30, 2016
@DzmitryShylovich
Copy link
Contributor

DzmitryShylovich commented Dec 30, 2016

Will be fixed here #13593

@jbridger jbridger changed the title Lazy loaded module's resolve guard is not kept as singleton Lazy loaded module's resolver is not being kept as singleton Dec 30, 2016
@kimaina
Copy link

kimaina commented Jan 5, 2017

please review and merge the above PR

@onixie
Copy link

onixie commented Jan 10, 2017

Our team is facing a similar problem.
We rely a service which shares temporary states between components in a module.
But the lazy loaded module (injector) is recreated on every navigates that prevent state sharing.

@DzmitryShylovich
Copy link
Contributor

@pkozlowski-opensource duplicate of #12869

@pkozlowski-opensource
Copy link
Member

duplicate of #12869

@angular-automatic-lock-bot
Copy link

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Sep 10, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area: core Issues related to the framework runtime area: router
Projects
None yet
Development

No branches or pull requests

6 participants