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

Component under @defer can not find injected services - R3InjectorError(DeferBlock Injector) error. #56372

Closed
IgorKurkov opened this issue Jun 10, 2024 · 6 comments
Assignees
Labels
area: core Issues related to the framework runtime core: defer Issues related to @defer blocks. P3 An issue that is relevant to core functions, but does not impede progress. Important, but not urgent
Milestone

Comments

@IgorKurkov
Copy link

IgorKurkov commented Jun 10, 2024

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

core

Is this a regression?

Yes

Description

I'm encountering an issue where the component under @defer block can't achieve injected services in Angular 18.0.2.

However, this issue does not occur when using @if or moving out a component from the @defer { } scope.

unfortunately StackBlitz still buggy and doesn't want to load container with angular v18+, so will provide the example in text here.
Example:
modal root wrapper component for MatDialog:

@Component({
  standalone: true,
  providers: [BlaBlaService],
  selector: 'modal-host',
  templateUrl: 'modal-host.component.html',
})
export class ModalHostComponent { 
   data: IMatDialogData = inject(MAT_DIALOG_DATA);
}

Modal opening:
this.matDialog.open(ModalHostComponent, { ... parentComponent passing here ... })

parent component HTML

@defer (on timer(1s)) { // <-- DOES NOT WORK, returns "R3InjectorError(DeferBlock Injector) NullInjector error for BlaBlaService"
<!-- @if(anyCondition) { --> // <--  WORKS, no error
   ...
  @switch (true) {
    @case ...
     ...
    @default {
      <!-- defer issue can't load component with its injections -->
      <child-component /> 
    }
  }
}

parent component TS:

@Component({
  standalone: true,
  imports: [ChildComponent],
  selector: 'app-parent',
  templateUrl: 'app-parent.component.html',
})
export class AppParent {}

child: which uses service from modal wrapper component

@Component({
  standalone: true,
  selector: 'child-component',
  template: `child works`
})
export class ChildComponent {
  private service = inject(BlaBlaService); // <-- from chain Child -> Parent -> ModalHostComponent (has BlaBlaService)

   constructor() {
     this.service.doJob();
  }
}

Please provide a link to a minimal reproduction of the bug

No response

Please provide the exception or error you saw

ERROR NullInjectorError: R3InjectorError(DeferBlock Injector)[BlaBlaService -> BlaBlaService -> BlaBlaService]: 
  NullInjectorError: No provider for BlaBlaService!
    at NullInjector.get (core.mjs:1659:27)
    at R3Injector.get (core.mjs:3105:33)
    at R3Injector.get (core.mjs:3105:33)
    at R3Injector.get (core.mjs:3105:33)
    at lookupTokenUsingModuleInjector (core.mjs:5746:39)
    at getOrCreateInjectable (core.mjs:5794:12)
    at ɵɵdirectiveInject (core.mjs:11232:19)
    at ɵɵinject (core.mjs:1112:60)
    at inject (core.mjs:1198:12)
    at new ChildComponent

Please provide the environment you discovered this bug in (run ng version)

Angular CLI: 18.0.2
Node: 20.10.0
Package Manager: npm 10.2.3

Angular: 18.0.1
... animations, cdk, common, compiler, compiler-cli, core, forms
... language-service, material, platform-browser
... platform-browser-dynamic, platform-server, router

Package                         Version
---------------------------------------------------------
@angular-devkit/architect       0.1800.2
@angular-devkit/build-angular   18.0.2
@angular-devkit/core            18.0.2
@angular-devkit/schematics      18.0.2
@angular/cli                    18.0.2
@angular/ssr                    18.0.2
@schematics/angular             18.0.2
ng-packagr                      18.0.0
rxjs                            7.8.1
typescript                      5.4.5
zone.js                         0.14.6

Anything else?

this issue possibly related to this one, but it is different according to newest version and DeferBlock error naming as possibly implemented. #54117

@AndrewKushnir AndrewKushnir added area: core Issues related to the framework runtime core: defer Issues related to @defer blocks. labels Jun 10, 2024
@ngbot ngbot bot added this to the needsTriage milestone Jun 10, 2024
@AndrewKushnir AndrewKushnir added the needs reproduction This issue needs a reproduction in order for the team to investigate further label Jun 10, 2024
@ngbot ngbot bot modified the milestones: needsTriage, Backlog Jun 10, 2024
@AndrewKushnir
Copy link
Contributor

@IgorKurkov thanks for reporting this issue. Could you please create a minimal reproduction scenario (in a form of a Github repository), so that we can perform further investigation?

@montella1507
Copy link

montella1507 commented Jun 13, 2024

Have the same problem... still cannot simulate in minimal reproduction :-/

It may be somehow connected to components created dynamically and lazily with viewContainer.createComponent()

It is strange.

  1. Token is EditorStore class
  2. this.parent.parent.parent.source is EditorComponent, which is "singleton" in applicartion
  3. EditorComponent provides that EditorStore class
  4. EditorComponent HAS that editorStore class, when i check it with ng.getComponent()
image image

Have to mention.. is id dynamically created tree via:

  1. dynamic component import('@...).then(x=>x.Type)
  2. created with container.createComponent(type, { injector: this.injector })

@montella1507
Copy link

@AndrewKushnir do you think it is possible that the inheritance may be problem?

I got this error:
Error: NullInjectorError: No provider for EditorStore!

However... EditorStore is there... in that component.

@AndrewKushnir AndrewKushnir self-assigned this Jun 23, 2024
@AndrewKushnir AndrewKushnir added P3 An issue that is relevant to core functions, but does not impede progress. Important, but not urgent and removed needs reproduction This issue needs a reproduction in order for the team to investigate further labels Jun 28, 2024
@AndrewKushnir
Copy link
Contributor

Quick update: we've reproduced the issue and found the origin of the problem. I'll be working on a fix, but there is no ETA at this moment. Will keep this thread updated once I have more info.

AndrewKushnir added a commit to AndrewKushnir/angular that referenced this issue Jun 28, 2024
…ttached to ApplicationRef

This commit updates the logic that create an injector for defer blocks (when it's needed) to account for a situation when a component is instantiated without a connection to the current component tree. This can happen if a component is created using its factory function or via `createComponent()` call.

Resolves angular#56372.
AndrewKushnir added a commit to AndrewKushnir/angular that referenced this issue Jun 29, 2024
…ttached to ApplicationRef

This commit updates the logic that create an injector for defer blocks (when it's needed) to account for a situation when a component is instantiated without a connection to the current component tree. This can happen if a component is created using its factory function or via `createComponent()` call.

Resolves angular#56372.
thePunderWoman pushed a commit that referenced this issue Jul 3, 2024
…ttached to ApplicationRef (#56763)

This commit updates the logic that create an injector for defer blocks (when it's needed) to account for a situation when a component is instantiated without a connection to the current component tree. This can happen if a component is created using its factory function or via `createComponent()` call.

Resolves #56372.

PR Close #56763
thePunderWoman pushed a commit that referenced this issue Jul 3, 2024
…ttached to ApplicationRef (#56763)

This commit updates the logic that create an injector for defer blocks (when it's needed) to account for a situation when a component is instantiated without a connection to the current component tree. This can happen if a component is created using its factory function or via `createComponent()` call.

Resolves #56372.

PR Close #56763
@AndrewKushnir
Copy link
Contributor

FYI, the fix for the reported issue has landed and was released to NPM as a part of Angular 18.0.6 packages. Please try updating to Angular 18.0.6 and let us know if the problem still exists. Thank you.

@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 Aug 3, 2024
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 core: defer Issues related to @defer blocks. P3 An issue that is relevant to core functions, but does not impede progress. Important, but not urgent
Projects
None yet
3 participants