diff --git a/packages/core/src/render3/di.ts b/packages/core/src/render3/di.ts index b4b34a8e7a67e..713706727737f 100644 --- a/packages/core/src/render3/di.ts +++ b/packages/core/src/render3/di.ts @@ -334,7 +334,7 @@ export function injectAttributeImpl(tNode: TNode, attrNameToInject: string): str function notFoundValueOrThrow( notFoundValue: T|null, token: ProviderToken, flags: InjectFlags): T|null { - if (flags & InjectFlags.Optional) { + if ((flags & InjectFlags.Optional) || notFoundValue !== undefined) { return notFoundValue; } else { throwProviderNotFoundError(token, 'NodeInjector'); @@ -352,7 +352,7 @@ function notFoundValueOrThrow( */ function lookupTokenUsingModuleInjector( lView: LView, token: ProviderToken, flags: InjectFlags, notFoundValue?: any): T|null { - if (flags & InjectFlags.Optional && notFoundValue === undefined) { + if ((flags & InjectFlags.Optional) && notFoundValue === undefined) { // This must be set or the NullInjector will throw for optional deps notFoundValue = null; } diff --git a/packages/core/test/acceptance/di_spec.ts b/packages/core/test/acceptance/di_spec.ts index 6b90f60b8f93a..642981f24224e 100644 --- a/packages/core/test/acceptance/di_spec.ts +++ b/packages/core/test/acceptance/di_spec.ts @@ -1025,6 +1025,24 @@ describe('di', () => { const dirC = fixture.componentInstance.dirC; expect(dirC.dirB).toBeNull(); }); + + it('should imply @Optional in presence of a default value', () => { + const NON_EXISTING_PROVIDER = new InjectionToken('non-existing'); + + @Component({template: ''}) + class MyComp { + value: string|undefined; + constructor(injector: Injector) { + this.value = injector.get(NON_EXISTING_PROVIDER, 'default', InjectFlags.Host); + } + } + + const injector = Injector.create({providers: []}); + expect(injector.get(NON_EXISTING_PROVIDER, 'default', InjectFlags.Host)).toBe('default'); + + const fixture = TestBed.createComponent(MyComp); + expect(fixture.componentInstance.value).toBe('default'); + }); }); it('should check only the current node with @Self', () => {