fix(core): make injector.get() return default value with InjectFlags.Self flag on (#27739)
Fixes #27729 PR Close #27739
This commit is contained in:
parent
e1065eec5b
commit
0477bfc8ed
|
@ -342,6 +342,10 @@ function resolveToken(
|
||||||
}
|
}
|
||||||
} else if (!(flags & InjectFlags.Self)) {
|
} else if (!(flags & InjectFlags.Self)) {
|
||||||
value = parent.get(token, notFoundValue, InjectFlags.Default);
|
value = parent.get(token, notFoundValue, InjectFlags.Default);
|
||||||
|
} else if (!(flags & InjectFlags.Optional)) {
|
||||||
|
value = Injector.NULL.get(token, notFoundValue);
|
||||||
|
} else {
|
||||||
|
value = Injector.NULL.get(token, typeof notFoundValue !== 'undefined' ? notFoundValue : null);
|
||||||
}
|
}
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
|
@ -197,7 +197,12 @@ export class R3Injector {
|
||||||
// Select the next injector based on the Self flag - if self is set, the next injector is
|
// Select the next injector based on the Self flag - if self is set, the next injector is
|
||||||
// the NullInjector, otherwise it's the parent.
|
// the NullInjector, otherwise it's the parent.
|
||||||
const nextInjector = !(flags & InjectFlags.Self) ? this.parent : getNullInjector();
|
const nextInjector = !(flags & InjectFlags.Self) ? this.parent : getNullInjector();
|
||||||
return nextInjector.get(token, flags & InjectFlags.Optional ? null : notFoundValue);
|
// Set the notFoundValue based on the Optional flag - if optional is set and notFoundValue
|
||||||
|
// is undefined, the value is null, otherwise it's the notFoundValue.
|
||||||
|
notFoundValue = (flags & InjectFlags.Optional) && notFoundValue === THROW_IF_NOT_FOUND ?
|
||||||
|
null :
|
||||||
|
notFoundValue;
|
||||||
|
return nextInjector.get(token, notFoundValue);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (e.name === 'NullInjectorError') {
|
if (e.name === 'NullInjectorError') {
|
||||||
const path: any[] = e[NG_TEMP_TOKEN_PATH] = e[NG_TEMP_TOKEN_PATH] || [];
|
const path: any[] = e[NG_TEMP_TOKEN_PATH] = e[NG_TEMP_TOKEN_PATH] || [];
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
* found in the LICENSE file at https://angular.io/license
|
* found in the LICENSE file at https://angular.io/license
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {Inject, InjectionToken, Injector, Optional, Self, SkipSelf, forwardRef} from '@angular/core';
|
import {Inject, InjectFlags, InjectionToken, Injector, Optional, Self, SkipSelf, forwardRef} from '@angular/core';
|
||||||
import {expect} from '@angular/platform-browser/testing/src/matchers';
|
import {expect} from '@angular/platform-browser/testing/src/matchers';
|
||||||
import {ivyEnabled, modifiedInIvy} from '@angular/private/testing';
|
import {ivyEnabled, modifiedInIvy} from '@angular/private/testing';
|
||||||
|
|
||||||
|
@ -421,6 +421,35 @@ function factoryFn(a: any){}
|
||||||
`${injectorName}Error[${stringify(Car)} -> ${stringify(Engine)}]: \n` +
|
`${injectorName}Error[${stringify(Car)} -> ${stringify(Engine)}]: \n` +
|
||||||
' NullInjectorError: No provider for Engine!');
|
' NullInjectorError: No provider for Engine!');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should return a default value when not requested provider on self', () => {
|
||||||
|
const car = new SportsCar(new Engine());
|
||||||
|
const injector = Injector.create([]);
|
||||||
|
expect(injector.get<Car|null>(Car, null, InjectFlags.Self)).toBeNull();
|
||||||
|
expect(injector.get<Car>(Car, car, InjectFlags.Self)).toBe(car);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return a default value when not requested provider on self and optional', () => {
|
||||||
|
const flags = InjectFlags.Self | InjectFlags.Optional;
|
||||||
|
const injector = Injector.create([]);
|
||||||
|
expect(injector.get<Car|null>(Car, null, InjectFlags.Self)).toBeNull();
|
||||||
|
expect(injector.get<Car|number>(Car, 0, flags)).toBe(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
it(`should return null when not requested provider on self and optional`, () => {
|
||||||
|
const flags = InjectFlags.Self | InjectFlags.Optional;
|
||||||
|
const injector = Injector.create([]);
|
||||||
|
expect(injector.get<Car|null>(Car, undefined, flags)).toBeNull();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should throw error when not requested provider on self', () => {
|
||||||
|
const injector = Injector.create([]);
|
||||||
|
const injectorName = ivyEnabled ? `R3Injector` : `StaticInjector`;
|
||||||
|
expect(() => injector.get(Car, undefined, InjectFlags.Self))
|
||||||
|
.toThrowError(
|
||||||
|
`${injectorName}Error[${stringify(Car)}]: \n` +
|
||||||
|
` NullInjectorError: No provider for ${stringify(Car)}!`);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('default', () => {
|
describe('default', () => {
|
||||||
|
|
Loading…
Reference in New Issue