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

reading required signal input from effect causes error NG0950 when done inside structural directive creating an embedded view after promise resolves #55311

Open
jnizet opened this issue Apr 12, 2024 · 5 comments
Labels
area: core Issues related to the framework runtime bug core: reactivity Work related to fine-grained reactivity in the core framework cross-cutting: signals P1 Impacts a large percentage of users; if a workaround exists it is partial or overly painful
Milestone

Comments

@jnizet
Copy link
Contributor

jnizet commented Apr 12, 2024

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

core

Is this a regression?

No

Description

When using a directive which defines an effect reading a required signal input from inside an ng-container using a structural directive which renders its view after a promise resolves, an error NG0950 (Input is required but no value is available yet) is thrown.

The same code works fine when used outside of the container with the structural directive.

Please provide a link to a minimal reproduction of the bug

https://stackblitz.com/edit/stackblitz-starters-nk7kmy?file=src%2Fbug.directive.ts,src%2Ffoo.directive.ts,src%2Fmain.ts

Please provide the exception or error you saw

Error: NG0950: Input is required but no value is available yet. Find more at https://angular.io/errors/NG0950
    at _BugDirective.inputValueFn [as title] (chunk-BKDHUOG3.js?v=8ee0a5cd:3411:13)
    at EffectHandle.effectFn (main.ts:21:24)
    at EffectHandle.runEffect (chunk-BKDHUOG3.js?v=8ee0a5cd:24021:12)
    at Object.fn (chunk-BKDHUOG3.js?v=8ee0a5cd:24016:52)
    at Object.run (chunk-BKDHUOG3.js?v=8ee0a5cd:341:12)
    at EffectHandle.run (chunk-BKDHUOG3.js?v=8ee0a5cd:24028:18)
    at ZoneAwareEffectScheduler.flushQueue (chunk-BKDHUOG3.js?v=8ee0a5cd:24006:14)
    at chunk-BKDHUOG3.js?v=8ee0a5cd:23997:31
    at _ZoneDelegate.invoke (zone__js.js?v=a72eca7f:299:158)
    at Object.onInvoke (chunk-BKDHUOG3.js?v=8ee0a5cd:12023:25)

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

Angular CLI: 17.3.4
Node: 18.18.0
Package Manager: npm 10.2.3
OS: linux x64

Angular: 17.3.4
... animations, cli, common, compiler, compiler-cli, core, forms
... platform-browser, router

Package                         Version
---------------------------------------------------------
@angular-devkit/architect       0.1703.4
@angular-devkit/build-angular   17.3.4
@angular-devkit/core            17.3.4
@angular-devkit/schematics      17.3.4
@schematics/angular             17.3.4
rxjs                            7.8.1
typescript                      5.3.3
zone.js                         0.14.4

Anything else?

No response

@JeanMeche
Copy link
Member

JeanMeche commented Apr 12, 2024

Hi JB !
Is there any reason you opened the issue on the FW and not the transloco repo ? Structural directives provided by the framework like NgIf don't have this issue. It look like it's a problem the way transloco projects the content of the directive.

@jnizet
Copy link
Contributor Author

jnizet commented Apr 12, 2024

Hi Matthieu

I assumed that whatever Transloco is doing in its directive shouldn't have an impact on how Angular schedules the execution of an effect: it should be executed after the input has been set, and not before.
Isn't that a reasonable assumption?

@JeanMeche
Copy link
Member

The first effect execution is scheduled to run during the first CD. Transloco is probably triggering a CD before the input has been set.

@jnizet jnizet changed the title reading required signal input from effect causes error NG0950 when done inside transloco structural directive reading required signal input from effect causes error NG0950 when done inside structural directive creating an embedded view after promise resolves Apr 12, 2024
@jnizet
Copy link
Contributor Author

jnizet commented Apr 12, 2024

I've edited the issue to provide a minimal structural directive that reproduces the issue. All it takes is the following, which looks quite innocent to me:

export class FooDirective implements OnInit {
  private tpl = inject(TemplateRef);
  private vcr = inject(ViewContainerRef);

  ngOnInit() {
    Promise.resolve().then(() => {
      this.vcr.createEmbeddedView(this.tpl, {});
    });
  }
}

@JeanMeche JeanMeche added area: core Issues related to the framework runtime cross-cutting: signals labels Apr 12, 2024
@ngbot ngbot bot modified the milestone: needsTriage Apr 12, 2024
@alxhub alxhub added P1 Impacts a large percentage of users; if a workaround exists it is partial or overly painful bug labels Apr 12, 2024
@ngbot ngbot bot modified the milestones: needsTriage, Backlog Apr 12, 2024
@alxhub
Copy link
Member

alxhub commented Apr 12, 2024

Thank you for the excellent minimal reproduction.

Yep, this is indeed a bug. Digging in, the problem seems to be with the ChangeDetectorRef trick we're using in effect() to know if we're inside a view that has been initialized or not.

When BugDirective calls effect(), we use the LView to decide if the first update pass is already complete (see the code). The ChangeDetectorRef though gives us the LView of the parent component, which of course has already been initialized. Thus we don't defer the effect from scheduling immediately, causing the issue.

@alxhub alxhub added the core: reactivity Work related to fine-grained reactivity in the core framework label Apr 12, 2024
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 bug core: reactivity Work related to fine-grained reactivity in the core framework cross-cutting: signals P1 Impacts a large percentage of users; if a workaround exists it is partial or overly painful
Projects
None yet
Development

No branches or pull requests

3 participants