Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/core/src/application_ref.ts
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@ export class PlatformRef {
const ngZoneInjector = Injector.create(
{providers: providers, parent: this.injector, name: moduleFactory.moduleType.name});
const moduleRef = <InternalNgModuleRef<M>>moduleFactory.create(ngZoneInjector);
const exceptionHandler: ErrorHandler = moduleRef.injector.get(ErrorHandler, null);
const exceptionHandler = moduleRef.injector.get(ErrorHandler, null);
if (!exceptionHandler) {
throw new Error('No ErrorHandler. Is platform module (BrowserModule) included?');
}
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/di.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export * from './di/metadata';
export {InjectableType, InjectorType, defineInjectable, defineInjector} from './di/defs';
export {forwardRef, resolveForwardRef, ForwardRefFn} from './di/forward_ref';
export {Injectable, InjectableDecorator, InjectableProvider} from './di/injectable';
export {inject, InjectFlags, INJECTOR, Injector} from './di/injector';
export {inject, InjectFlags, INJECTOR, Injector, ThrowIfNotFound} from './di/injector';
export {ReflectiveInjector} from './di/reflective_injector';
export {StaticProvider, ValueProvider, ConstructorSansProvider, ExistingProvider, FactoryProvider, Provider, TypeProvider, ClassProvider} from './di/provider';
export {createInjector} from './di/r3_injector';
Expand Down
33 changes: 27 additions & 6 deletions packages/core/src/di/injector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,15 @@ import {Inject, Optional, Self, SkipSelf} from './metadata';
import {ConstructorProvider, ExistingProvider, FactoryProvider, StaticClassProvider, StaticProvider, ValueProvider} from './provider';

export const SOURCE = '__source';
const _THROW_IF_NOT_FOUND = new Object();
/** Supporting type for Injector.get */
export class ThrowIfNotFound {
private constructor() {
if (_THROW_IF_NOT_FOUND) {
throw new Error('Do not instantiate ThrowIfNotFound; use THROW_IF_NOT_FOUND instead.');
}
}
}
const _THROW_IF_NOT_FOUND: ThrowIfNotFound = new (<any>ThrowIfNotFound)();
export const THROW_IF_NOT_FOUND = _THROW_IF_NOT_FOUND;

/**
Expand Down Expand Up @@ -62,12 +70,23 @@ export abstract class Injector {
static THROW_IF_NOT_FOUND = _THROW_IF_NOT_FOUND;
static NULL: Injector = new NullInjector();

/**
* Retrieves an instance from the injector based on the provided token.
* @returns The instance from the injector if defined.
* @throws When `token` does not resolve to an instance.
*/
abstract get<T>(
token: Type<T>|InjectionToken<T>, notFoundValue?: ThrowIfNotFound|undefined,
flags?: InjectFlags): T;
/**
* Retrieves an instance from the injector based on the provided token.
* @returns The instance from the injector if defined, otherwise the `notFoundValue`.
* @throws When the `notFoundValue` is `undefined` or `Injector.THROW_IF_NOT_FOUND`.
* @throws When `token` does not resolve to an instance and the `notFoundValue`
* is `undefined` or `Injector.THROW_IF_NOT_FOUND`.
*/
abstract get<T>(token: Type<T>|InjectionToken<T>, notFoundValue?: T, flags?: InjectFlags): T;
abstract get<T, U>(
token: Type<T>|InjectionToken<T>, notFoundValue: U|ThrowIfNotFound|undefined,
flags?: InjectFlags): T|U;
/**
* @deprecated from v4.0.0 use Type<T> or InjectionToken<T>
* @suppress {duplicate}
Expand Down Expand Up @@ -148,7 +167,10 @@ export class StaticInjector implements Injector {
recursivelyProcessProviders(records, providers);
}

get<T>(token: Type<T>|InjectionToken<T>, notFoundValue?: T, flags?: InjectFlags): T;
get<T>(token: Type<T>, notFoundValue?: ThrowIfNotFound|undefined, flags?: InjectFlags): T;
get<T, U>(
token: Type<T>|InjectionToken<T>, notFoundValue: U|ThrowIfNotFound|undefined,
flags?: InjectFlags): T|U;
get(token: any, notFoundValue?: any): any;
get(token: any, notFoundValue?: any, flags: InjectFlags = InjectFlags.Default): any {
const record = this._records.get(token);
Expand Down Expand Up @@ -324,8 +346,7 @@ function resolveToken(
// If we don't know how to resolve dependency and we should not check parent for it,
// than pass in Null injector.
!childRecord && !(options & OptionFlags.CheckParent) ? NULL_INJECTOR : parent,
options & OptionFlags.Optional ? null : Injector.THROW_IF_NOT_FOUND,
InjectFlags.Default));
options & OptionFlags.Optional ? null : _THROW_IF_NOT_FOUND, InjectFlags.Default));
}
}
record.value = value = useNew ? new (fn as any)(...deps) : fn.apply(obj, deps);
Expand Down
5 changes: 5 additions & 0 deletions packages/core/test/di/injector_spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ import {describe, expect, it} from '@angular/core/testing/src/testing_internal';
.toThrowError('NullInjectorError: No provider for someToken!');
});

it('should throw if undefined is given', () => {
expect(() => Injector.NULL.get('someToken', undefined))
.toThrowError('NullInjectorError: No provider for someToken!');
});

it('should return the default value',
() => { expect(Injector.NULL.get('someToken', 'notFound')).toEqual('notFound'); });
});
Expand Down
8 changes: 6 additions & 2 deletions tools/public_api_guard/core/core.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -392,10 +392,11 @@ export declare class InjectionToken<T> {
}

export declare abstract class Injector {
abstract get<T>(token: Type<T> | InjectionToken<T>, notFoundValue?: T, flags?: InjectFlags): T;
abstract get<T>(token: Type<T> | InjectionToken<T>, notFoundValue?: ThrowIfNotFound | undefined, flags?: InjectFlags): T;
abstract get<T, U>(token: Type<T> | InjectionToken<T>, notFoundValue: U | ThrowIfNotFound | undefined, flags?: InjectFlags): T | U;
/** @deprecated */ abstract get(token: any, notFoundValue?: any): any;
static NULL: Injector;
static THROW_IF_NOT_FOUND: Object;
static THROW_IF_NOT_FOUND: ThrowIfNotFound;
static ngInjectableDef: never;
/** @deprecated */ static create(providers: StaticProvider[], parent?: Injector): Injector;
static create(options: {
Expand Down Expand Up @@ -861,6 +862,9 @@ export declare class TestabilityRegistry {
unregisterApplication(token: any): void;
}

export declare class ThrowIfNotFound {
}

export interface TrackByFunction<T> {
(index: number, item: T): any;
}
Expand Down