Skip to content

[ivy/ngcc] Fails to inject optional dependency in Angular8 library #17063

Closed
@PapaNappa

Description

@PapaNappa

🐞 bug report

Affected Package

The issue is caused by package @angular/core or ngcc

Is this a regression?

Yes, the previous version in which this bug was not present was: 8

Description

I have a library (still building with Angular8 for backwards compatibility) that has one main service Lib2Service:

@Injectable({ providedIn: 'root' })
export class Lib2Service {
  constructor(
      @Optional() private lib1: BaseLib1 | null,
  ) {}

  getValue() {
    if (this.lib1) return this.lib1.getValue();
    return -1;
  }
}

This Lib2Service takes an optional service BaseLib1.
The use case is to provide plugins to this service.

In this example, the 'plugin' BaseLib1 has only a single method:

export class BaseLib1 {
  getValue() {
    return 0;
  }
}

The Angular8 library also provides a default implementation Lib1Service:

@Injectable()
export class Lib1Service extends BaseLib1 {
  getValue() {
    return 1;
  }
}

The intended use in any app is then to provide a certain implementation of BaseLib1, e.g. like so using the default implementation:

@NgModule({
  declarations: [AppComponent],
  imports: [BrowserModule],
  providers: [
    Lib1Service,
    { provide: BaseLib1, useExisting: Lib1Service },
  ],
  bootstrap: [AppComponent]
})
export class AppModule {
}

Then, any component can use Lib2Service, like so:

@Component({
  selector: 'app-root',
  template: `
      lib service: {{lib2Service.getValue()}}
  `,
  styles: []
})
export class AppComponent {
  constructor(
      public lib2Service: Lib2Service,
  ) {
  }
}

This works fine when the app is also using Angular 8, but with Angular 9, Lib2Service is constructed with its lib1 parameter undefined.

If I add @Inject(BaseLib1) to the ctor parameter of Lib2Service, the dependency is injected correctly. However, this was not necessary with an Angular 8 app and breaks the existing version of the library.

🔬 Minimal Reproduction

I have reproduced the Angular 9 app at https://github.com/PapaNappa/Angular9-DI-Bug
It contains a .tgz of the Angular8 library, which is basically the three classes from the top of this post.

Steps to reproduce:

  1. git clone https://github.com/PapaNappa/Angular9-DI-Bug
  2. cd Angular9-DI-Bug
  3. npm install
  4. ng serve
  5. Open the app
  6. The app should output the value 1 from Lib1Service, put it actually prints -1 indicating that the optional dependency lib1 is not provided to Lib2Service.

🌍 Your Environment

Angular Version (library):


Angular CLI: 8.3.25
Node: 12.14.1
OS: win32 x64
Angular: 8.2.14
... animations, common, compiler, compiler-cli, core, forms
... language-service, platform-browser, platform-browser-dynamic
... router

Package                            Version
------------------------------------------------------------
@angular-devkit/architect          0.803.25
@angular-devkit/build-angular      0.803.25
@angular-devkit/build-ng-packagr   0.803.25
@angular-devkit/build-optimizer    0.803.25
@angular-devkit/build-webpack      0.803.25
@angular-devkit/core               8.3.25
@angular-devkit/schematics         8.3.25
@angular/cli                       8.3.25
@ngtools/webpack                   8.3.25
@schematics/angular                8.3.25
@schematics/update                 0.803.25
ng-packagr                         5.7.1
rxjs                               6.4.0
typescript                         3.5.3
webpack                            4.39.2

Angular Version (app):


Angular CLI: 9.0.1
Node: 12.14.1
OS: win32 x64

Angular: 9.0.0
... animations, common, compiler, compiler-cli, core, forms
... language-service, platform-browser, platform-browser-dynamic
... router
Ivy Workspace: Yes

Package                            Version
------------------------------------------------------------
@angular-devkit/architect          0.900.1
@angular-devkit/build-angular      0.900.1
@angular-devkit/build-ng-packagr   0.900.1
@angular-devkit/build-optimizer    0.900.1
@angular-devkit/build-webpack      0.900.1
@angular-devkit/core               9.0.1
@angular-devkit/schematics         9.0.1
@angular/cli                       9.0.1
@ngtools/webpack                   9.0.1
@schematics/angular                9.0.1
@schematics/update                 0.900.1
ng-packagr                         9.0.0
rxjs                               6.5.4
typescript                         3.7.5
webpack                            4.41.2

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions