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

DI: Resolve Guard and Component both create a service which is 'provided' in a lazy loaded module #13870

Closed
jeanpaulattard opened this issue Jan 11, 2017 · 7 comments

Comments

@jeanpaulattard
Copy link

jeanpaulattard commented Jan 11, 2017

I'm submitting a ... (check one with "x")

[x ] bug report => search github for a similar issue or PR before submitting

I've encountered an issue where a resolve route-guard did not share the same service with a component that is registered to the same module the Resolve guard is.

I have a scenario where the resolve guard of a route bound to a lazy loaded module retrieves a list of data from the backend and caches it on a variable within the service. The same service has another method (that is called from a component) which retrieves fine grained data, first by looking within the cached data, and if not found retrievs that particular subset of data from backend. The issue is that the the Service is recreated when the component is visited as well, thus losing the cached data.

I've been boggling my mind around this issue and I cannot seem to make sense of what is happening. I've read the docs on dependency injection, hierarchical injection and modules. From my understanding the application has a root injector which is bound to the AppModule that is bootstrapped. Child injectors are created for each component, and for each lazy loaded module. Whenever a Service is needed, first the service is looked within the injector bound to the Component, and if not found, checkes in the parent component, and continues going up through the injector tree until reaching the module injector (and if not found here throws an error).

Now if the Service I needed is 'provided' within the lazy loaded module, shouldn't the Resolve guard and the component share the same Singleton Service bound to the module injector? I'm reporting this as a bug because 1) the docs does imply that, and 2) this problem seems to be occuring only with injectors of lazy loaded modules, and not the root module. See the following plunker.

https://plnkr.co/edit/G6I7m8duZMOCFdnuuk3l?p=preview

When a service bound to the root module is used by both the Resolve guard and the Component, the service is shared... However when the same logic is applied to the lazy loaded module, the service is created and recreated both when the Resolve Guard is instantiated and when the Component is instantiated respectively. The plunker above demos it. The logic for the retrieval of data in the root module and lazy loaded module is the same (different services/components ofcourse), however the creation of the service behave differently.

Expected behavior
Only one instance of the Service 'provided' in the lazy loaded module should be created when accessed via the resolve guard, and a second creation (which overrides the first creation) SHOULD NOT take place when the Component is accessed.

Minimal reproduction of the problem with instructions

https://plnkr.co/edit/G6I7m8duZMOCFdnuuk3l?p=preview

Please tell us about your environment:

Operating system: windows 10
IDE: Webstorm
Package manager: NPM
HTTP server: Webpack dev server

  • Angular version: 2.4.2

  • Language: Typescript 2.0.10

@DzmitryShylovich
Copy link
Contributor

Yeah, it's a known issue. See #12869

@jeanpaulattard
Copy link
Author

Hi @DzmitryShylovich , thanks for getting my attention to it.

@guidoffm
Copy link

I have the same problem. I want to initialize some things in services. I have set a CanActivate guard for the root component of the lazy loaded feature module. The guard should initialize all the services before starting the feature module. This works. But then, when I access a service from a component the service is created again. Maybe someone has work around for this.

@rhessus
Copy link

rhessus commented Jan 15, 2017

I have the same problem :(

@readren
Copy link

readren commented Jan 19, 2017

Mee too. A work around is downgrading the router to version 3.1.x.
I'm using router version 3.1.1 with core version 2.4.2 with no apparent issues other than unmet peer dependency messages.

@DzmitryShylovich
Copy link
Contributor

@pkozlowski-opensource duplicate of #12869

vicb added a commit to vicb/angular that referenced this issue Mar 10, 2017
fixes angular#12869
fixes angular#12889
fixes angular#13885
fixes angular#13870

Before this change there was a single injector tree.
Now we have 2 injector trees, one for the modules and one for the components.
This fixes lazy loading modules.

See the design docs for details:
https://docs.google.com/document/d/1OEUIwc-s69l1o97K0wBd_-Lth5BBxir1KuCRWklTlI4

BREAKING CHANGES

`ComponentFactory.create()` takes an extra optional `NgModuleRef` parameter.
No change should be required in user code as the correct module will be used
when none is provided

DEPRECATIONS

The following methods were used internally and are no more required:
- `RouterOutlet.locationFactoryResolver`
- `RouterOutlet.locationInjector`
vicb added a commit to vicb/angular that referenced this issue Mar 10, 2017
fixes angular#12869
fixes angular#12889
fixes angular#13885
fixes angular#13870

Before this change there was a single injector tree.
Now we have 2 injector trees, one for the modules and one for the components.
This fixes lazy loading modules.

See the design docs for details:
https://docs.google.com/document/d/1OEUIwc-s69l1o97K0wBd_-Lth5BBxir1KuCRWklTlI4

BREAKING CHANGES

`ComponentFactory.create()` takes an extra optional `NgModuleRef` parameter.
No change should be required in user code as the correct module will be used
when none is provided

DEPRECATIONS

The following methods were used internally and are no more required:
- `RouterOutlet.locationFactoryResolver`
- `RouterOutlet.locationInjector`
vicb added a commit to vicb/angular that referenced this issue Mar 10, 2017
fixes angular#12869
fixes angular#12889
fixes angular#13885
fixes angular#13870

Before this change there was a single injector tree.
Now we have 2 injector trees, one for the modules and one for the components.
This fixes lazy loading modules.

See the design docs for details:
https://docs.google.com/document/d/1OEUIwc-s69l1o97K0wBd_-Lth5BBxir1KuCRWklTlI4

BREAKING CHANGES

`ComponentFactory.create()` takes an extra optional `NgModuleRef` parameter.
No change should be required in user code as the correct module will be used
when none is provided

DEPRECATIONS

The following methods were used internally and are no more required:
- `RouterOutlet.locationFactoryResolver`
- `RouterOutlet.locationInjector`
vicb added a commit to vicb/angular that referenced this issue Mar 13, 2017
fixes angular#12869
fixes angular#12889
fixes angular#13885
fixes angular#13870

Before this change there was a single injector tree.
Now we have 2 injector trees, one for the modules and one for the components.
This fixes lazy loading modules.

See the design docs for details:
https://docs.google.com/document/d/1OEUIwc-s69l1o97K0wBd_-Lth5BBxir1KuCRWklTlI4

BREAKING CHANGES

`ComponentFactory.create()` takes an extra optional `NgModuleRef` parameter.
No change should be required in user code as the correct module will be used
when none is provided

DEPRECATIONS

The following methods were used internally and are no more required:
- `RouterOutlet.locationFactoryResolver`
- `RouterOutlet.locationInjector`
chuckjaz pushed a commit that referenced this issue Mar 14, 2017
fixes #12869
fixes #12889
fixes #13885
fixes #13870

Before this change there was a single injector tree.
Now we have 2 injector trees, one for the modules and one for the components.
This fixes lazy loading modules.

See the design docs for details:
https://docs.google.com/document/d/1OEUIwc-s69l1o97K0wBd_-Lth5BBxir1KuCRWklTlI4

BREAKING CHANGES

`ComponentFactory.create()` takes an extra optional `NgModuleRef` parameter.
No change should be required in user code as the correct module will be used
when none is provided

DEPRECATIONS

The following methods were used internally and are no more required:
- `RouterOutlet.locationFactoryResolver`
- `RouterOutlet.locationInjector`
SamVerschueren pushed a commit to SamVerschueren/angular that referenced this issue Mar 18, 2017
fixes angular#12869
fixes angular#12889
fixes angular#13885
fixes angular#13870

Before this change there was a single injector tree.
Now we have 2 injector trees, one for the modules and one for the components.
This fixes lazy loading modules.

See the design docs for details:
https://docs.google.com/document/d/1OEUIwc-s69l1o97K0wBd_-Lth5BBxir1KuCRWklTlI4

BREAKING CHANGES

`ComponentFactory.create()` takes an extra optional `NgModuleRef` parameter.
No change should be required in user code as the correct module will be used
when none is provided

DEPRECATIONS

The following methods were used internally and are no more required:
- `RouterOutlet.locationFactoryResolver`
- `RouterOutlet.locationInjector`
smurfy pushed a commit to smurfy/angular that referenced this issue Apr 7, 2017
fixes angular#12869
fixes angular#12889
fixes angular#13885
fixes angular#13870

Before this change there was a single injector tree.
Now we have 2 injector trees, one for the modules and one for the components.
This fixes lazy loading modules.

See the design docs for details:
https://docs.google.com/document/d/1OEUIwc-s69l1o97K0wBd_-Lth5BBxir1KuCRWklTlI4

BREAKING CHANGES

`ComponentFactory.create()` takes an extra optional `NgModuleRef` parameter.
No change should be required in user code as the correct module will be used
when none is provided

DEPRECATIONS

The following methods were used internally and are no more required:
- `RouterOutlet.locationFactoryResolver`
- `RouterOutlet.locationInjector`
asnowwolf pushed a commit to asnowwolf/angular that referenced this issue Aug 11, 2017
fixes angular#12869
fixes angular#12889
fixes angular#13885
fixes angular#13870

Before this change there was a single injector tree.
Now we have 2 injector trees, one for the modules and one for the components.
This fixes lazy loading modules.

See the design docs for details:
https://docs.google.com/document/d/1OEUIwc-s69l1o97K0wBd_-Lth5BBxir1KuCRWklTlI4

BREAKING CHANGES

`ComponentFactory.create()` takes an extra optional `NgModuleRef` parameter.
No change should be required in user code as the correct module will be used
when none is provided

DEPRECATIONS

The following methods were used internally and are no more required:
- `RouterOutlet.locationFactoryResolver`
- `RouterOutlet.locationInjector`
juleskremer pushed a commit to juleskremer/angular that referenced this issue Aug 28, 2017
fixes angular#12869
fixes angular#12889
fixes angular#13885
fixes angular#13870

Before this change there was a single injector tree.
Now we have 2 injector trees, one for the modules and one for the components.
This fixes lazy loading modules.

See the design docs for details:
https://docs.google.com/document/d/1OEUIwc-s69l1o97K0wBd_-Lth5BBxir1KuCRWklTlI4

BREAKING CHANGES

`ComponentFactory.create()` takes an extra optional `NgModuleRef` parameter.
No change should be required in user code as the correct module will be used
when none is provided

DEPRECATIONS

The following methods were used internally and are no more required:
- `RouterOutlet.locationFactoryResolver`
- `RouterOutlet.locationInjector`
@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.
Projects
None yet
Development

No branches or pull requests

7 participants