components icon indicating copy to clipboard operation
components copied to clipboard

bug(cdk/dialog): parent injector not working correctly

Open DaSchTour opened this issue 10 months ago • 7 comments
trafficstars

Is this a regression?

  • [x] Yes, this behavior used to work in the previous version

The previous version in which this bug was not present was

18

Description

Tokens from the parent injector are not available. The behaviour is different between a ngComponentOutlet and the injector added to dialog

Reproduction

StackBlitz link: https://stackblitz.com/edit/stackblitz-starters-epebydgb Steps to reproduce: 1. 2.

Expected Behavior

Tokens from the parent injector are available

Actual Behavior

Tokens from parent injector are not available

Environment

     _                      _                 ____ _     ___
    / \   _ __   __ _ _   _| | __ _ _ __     / ___| |   |_ _|
   / △ \ | '_ \ / _` | | | | |/ _` | '__|   | |   | |    | |
  / ___ \| | | | (_| | |_| | | (_| | |      | |___| |___ | |
 /_/   \_\_| |_|\__, |\__,_|_|\__,_|_|       \____|_____|___|
                |___/
    

Angular CLI: 19.0.0
Node: 18.20.3
Package Manager: npm 10.2.3
OS: linux x64

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

Package                      Version
------------------------------------------------------
@angular-devkit/architect    0.1900.0
@angular-devkit/core         19.0.0
@angular-devkit/schematics   19.0.0
@angular/cdk                 19.0.5
@schematics/angular          19.0.0
rxjs                         7.8.1
typescript                   5.6.3
zone.js                      0.15.0

DaSchTour avatar Jan 13 '25 13:01 DaSchTour

One interesting thing is, that reproviding the token from the parent injector works. So this is the current workaround.

const token = this.injector.get(ROUTE_TOKEN);
const injector = Injector.create({
  providers: [
    { provide: SOME_TOKEN, useValue: 'Other Value' },
    { provide: ROUTE_TOKEN, useValue: token },
  ],
  parent: this.injector,
});

DaSchTour avatar Jan 13 '25 14:01 DaSchTour

Similar issue here using MatDialog, though nested: I can inject a service in the dialog component itself alone and it works, however if I have a nested component used inside the template of the dialog component that also injects the same service then it breaks in the same way as the reproduction above.

EDIT: Actually my issue was caused by a cyclic import https://github.com/angular/angular/issues/58802

us77ipis avatar Jan 22 '25 11:01 us77ipis

same issue here, it is a blocker for our upgrade

jmeinlschmidt avatar Feb 04 '25 11:02 jmeinlschmidt

@crisbeto, I’d appreciate it if you could prioritize this. The workaround suggested by @DaSchTour does work, but it’s quite inconvenient. While another option might be to use viewContainerRef, it’s not always applicable, such as when opening a dialog from an NGRX effect (unless we pass the viewContainerRef to the action, which is far from ideal). The amount of code required for the workaround is excessive, and it can vary significantly depending on the case, as the DI elements might be very different in each scenario. Passing the injector should be a straightforward solution, as it was in the latest 18.x version.

Could your team please give any ETA on this issue? Thank you!

Norby125 avatar Feb 15 '25 22:02 Norby125

bump

jmeinlschmidt avatar Mar 18 '25 16:03 jmeinlschmidt

@crisbeto as I can see label P4 was set with description "A relatively minor issue that is not relevant to core functions" - fully don't agree it is minor, it affects behavior of providers used in dialog, and you can realize something is wrong only in runtime.

yuri-apanasik avatar May 28 '25 15:05 yuri-apanasik

I wonder why this is so low priority although this is a regression. This worked before and somehow it stopped working. And the other very strange point is, that I can get the injection from the injector directly but not if it's set as a parent. I thought that this very strange behavior would get more attention from the team, as for me it seams that injection has some unexpected or unpredictable behavior.

DaSchTour avatar May 30 '25 16:05 DaSchTour

btw @DaSchTour if you pass 'viewContainerRef' instead of 'injector' into 'dialog.open' options everything works, checked in your StackBlitz (I mean ROUTE_TOKEN works as expected, SOME_TOKEN to be removed from dynamic.component to check)

yuri-apanasik avatar Jun 02 '25 13:06 yuri-apanasik

if you pass both 'injector' and 'viewContainerRef' then both tokens are ok

yuri-apanasik avatar Jun 02 '25 13:06 yuri-apanasik