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

Service provided in Wrapped Component but can´t be resolved, if wrappercomponent is used in template #43041

Open
Thomas-Lederer opened this issue Aug 4, 2021 · 4 comments
Labels
area: core Issues related to the framework runtime core: di P3 An issue that is relevant to core functions, but does not impede progress. Important, but not urgent
Milestone

Comments

@Thomas-Lederer
Copy link

Thomas-Lederer commented Aug 4, 2021

Which @angular/* package(s) are the source of the bug?

common

Is this a regression?

No

Description

In principal the Bug can be described the easiest in the following way:
The minimal reproduction of the bug contains of 3 components:

  • HostParentComponent: Does not provide a flowerservice. In its template is the HostComponent and the content is forwarded to the content of the HostComponent via <ng-content></ng-content>. Template = <app-host><ng-content></ng-content></app-host>

  • HostComponent: Provides the flowerservice. In its template the emoji property of the service is shown and the ng-content is displayed afterwards. Template = <p>Flower emoji: {{flower.emoji}}</p><ng-content></ng-content>

  • HostChildComponent: Does not provide a flowerservice, but tries to resolve the provided flowerservice and displays the emoji in the template. Template = <p>Flower emoji: {{flower ? flower.emoji : 'not resolvable as service is null !!!'}}</p>

Now the following two cases pointed out:
1.) Use of the HostParentComponent with the HostChildComponent as Content:
Template:
<app-host-parent> <app-host-child> </app-host-child> </app-host-parent>
Expected behaviour: As app-host-parent includes the HostComponent in its template, which provides the flowerservice, also the HostChildComponent should have access to this service.
Actual behaviour: The HostChildComponent can´t resolve the service !

2.) Use of the HostComponent with the HostChildComponent as Content:
Template:
<app-host> <app-host-child></app-host-child> </app-host>
Expected = Actual bahaviour: As the HostComponent provides the flowerservice, also the HostChildComponent has access to this instance of the service.

image

The attached figure illustrates the behavior just described.

Please provide a link to a minimal reproduction of the bug

https://stackblitz.com/edit/angular-omarrt?file=src/app/host-child/host-child.component.ts

Please provide the exception or error you saw

ERROR
Error: R3InjectorError(AppModule)[FlowerService -> FlowerService -> FlowerService]:
NullInjectorError: No provider for FlowerService!

Unhandled Promise rejection:
R3InjectorError(AppModule)[FlowerService -> FlowerService -> FlowerService]:
NullInjectorError: No provider for FlowerService!
; Zone:
<root>
; Task:
Promise.then
; Value:
Error: R3InjectorError(AppModule)[FlowerService -> FlowerService -> FlowerService]:
NullInjectorError: No provider for FlowerService!
NullInjectorError: R3InjectorError(AppModule)[FlowerService -> FlowerService -> FlowerService]:
NullInjectorError: No provider for FlowerService!
at NullInjector.get (https://angular-omarrt.stackblitz.io/turbo_modules/@angular/core@12.0.5/__ivy_ngcc__/bundles/core.umd.js:11586:29)
at R3Injector.get (https://angular-omarrt.stackblitz.io/turbo_modules/@angular/core@12.0.5/__ivy_ngcc__/bundles/core.umd.js:11758:37)
at R3Injector.get (https://angular-omarrt.stackblitz.io/turbo_modules/@angular/core@12.0.5/__ivy_ngcc__/bundles/core.umd.js:11758:37)
at R3Injector.get (https://angular-omarrt.stackblitz.io/turbo_modules/@angular/core@12.0.5/__ivy_ngcc__/bundles/core.umd.js:11758:37)
at NgModuleRef$1.get (https://angular-omarrt.stackblitz.io/turbo_modules/@angular/core@12.0.5/__ivy_ngcc__/bundles/core.umd.js:26035:37)
at Object.get (https://angular-omarrt.stackblitz.io/turbo_modules/@angular/core@12.0.5/__ivy_ngcc__/bundles/core.umd.js:25736:39)
at lookupTokenUsingModuleInjector (https://angular-omarrt.stackblitz.io/turbo_modules/@angular/core@12.0.5/__ivy_ngcc__/bundles/core.umd.js:3628:43)
at getOrCreateInjectable (https://angular-omarrt.stackblitz.io/turbo_modules/@angular/core@12.0.5/__ivy_ngcc__/bundles/core.umd.js:3741:16)
at Object.ɵɵdirectiveInject (https://angular-omarrt.stackblitz.io/turbo_modules/@angular/core@12.0.5/__ivy_ngcc__/bundles/core.umd.js:15255:16)
at NodeInjectorFactory.HostChildComponent_Factory [as factory] (https://angular-omarrt.stackblitz.io/~/src/app/host-child/host-child.component.ts:16:108)

Please provide the environment you discovered this bug in

package.json:

{
  "name": "ollxxdjmryo.angular",
  "version": "0.0.0",
  "private": true,
  "dependencies": {
    "rxjs": "6.6.7",
    "tslib": "2.3.0",
    "zone.js": "0.11.4",
    "jasmine-core": "3.7.1",
    "@angular/core": "12.0.5",
    "@angular/forms": "12.0.5",
    "@angular/common": "12.0.5",
    "@angular/router": "12.0.5",
    "@angular/compiler": "12.0.5",
    "@angular/animations": "12.0.5",
    "@angular/platform-browser": "12.0.5",
    "angular-in-memory-web-api": "0.11.0",
    "@angular/platform-browser-dynamic": "12.0.5"
  },
  "scripts": {
    "ng": "ng",
    "start": "ng serve",
    "build": "ng build",
    "test": "ng test",
    "lint": "ng lint",
    "e2e": "ng e2e"
  },
  "devDependencies": {
    "@angular-devkit/build-angular": "~0.1100.4",
    "@angular/cli": "~11.0.4",
    "@angular/compiler-cli": "~11.0.4",
    "@types/jasmine": "~3.6.0",
    "@types/node": "^12.11.1",
    "codelyzer": "^6.0.0",
    "jasmine-core": "~3.6.0",
    "jasmine-spec-reporter": "~5.0.0",
    "karma": "~5.1.0",
    "karma-chrome-launcher": "~3.1.0",
    "karma-coverage": "~2.0.3",
    "karma-jasmine": "~4.0.0",
    "karma-jasmine-html-reporter": "^1.5.0",
    "protractor": "~7.0.0",
    "ts-node": "~8.3.0",
    "tslint": "~6.1.0",
    "typescript": "~4.0.2"
  }
}

Anything else?

In the link for the minimal reproduction of the Bug, the error has been avoided as an @Optional has been written for the serviceinjection. To show the error again, just remove the @Optional in the HostChildComponent.

@djaud
Copy link

djaud commented Aug 4, 2021

+1

@pkozlowski-opensource pkozlowski-opensource added area: core Issues related to the framework runtime core: di labels Aug 4, 2021
@ngbot ngbot bot modified the milestone: needsTriage Aug 4, 2021
@Thomas-Lederer
Copy link
Author

Thomas-Lederer commented Aug 5, 2021 via email

@alxhub alxhub added the P3 An issue that is relevant to core functions, but does not impede progress. Important, but not urgent label Nov 16, 2022
@ngbot ngbot bot modified the milestones: needsTriage, Backlog Nov 16, 2022
@dadalxx
Copy link

dadalxx commented Mar 2, 2023

Hi Thomas-Lederer:
I am interested about ur description. I reproduce ur repo in ng14, of cause the result is same as you. So i debug the DI process step by step.

I found the connection between projected content and Host was setup at app-root. When u placed the app-host-child inside the app-host-parent, the app-host-child's host would link to app-host-parent. It's not determined by where the ng-content is.

So with DI process, when the FlowerService not found in HostChildComponent, it would find in its host who is HostParentComponent actually.

Otherwise, there is a another interest thing. I set a created time by Date.now() in each component. And the result like this:

image

The HostComponent created later then HostChildComponent. So it also comfirmed that there is no relationship between HostChildComponent and HostComponent.

I have no idea about whether the DI process is reasonable.

@Thomas-Lederer
Copy link
Author

Hi dadalxx,
many thanks for your input.
With your gained knowledge, the erroneous behavior can be understood even more. If the HostChild Component is created before the HostComponent, it makes sense that the service can not be consumed from the HostComponent.

However, I find this behavior unacceptable, as I would expect the content of a component to be created after the component itself in any case. But you may be right that it may not be a problem of DI at all, but a problem of scheduling when components are created.

Best regards
Thomas

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: core Issues related to the framework runtime core: di P3 An issue that is relevant to core functions, but does not impede progress. Important, but not urgent
Projects
None yet
Development

No branches or pull requests

5 participants