Compreendendo o contexto de injeção angular
May 02 2023
Angular introduziu a função inject() em versões recentes, o que nos permite obter uma referência a um provedor de maneira funcional, em vez de usar o método Injector.get().

Angular introduziu a inject()
função em versões recentes, o que nos permite obter uma referência a um provedor de forma funcional ao invés de usar o Injector.get()
método. No entanto, se você o usou ou uma biblioteca que o usa sob o capô, pode ter encontrado o seguinte erro:
inject() must be called from an injection context
such as a constructor, a factory function, a field initializer,
or a function used with `runInInjectionContext`.
Angular tem duas variáveis globais que podem conter um injector
em um determinado ponto no tempo: uma para an Injector
e outra para NodeInjector
. Aqui estão os trechos de código para ambos:
let _currentInjector = undefined;
export function getCurrentInjector() {
return _currentInjector;
}
export function setCurrentInjector(injector: Injector|undefined|null {
const former = _currentInjector;
_currentInjector = injector;
return former;
}
let _injectImplementation
export function getInjectImplementation() {
return _injectImplementation;
}
export function assertInInjectionContext(debugFn: Function): void {
if (!getInjectImplementation() && !getCurrentInjector()) {
throw new RuntimeError(
RuntimeErrorCode.MISSING_INJECTION_CONTEXT,
ngDevMode &&
(debugFn.name +
'() can only be used within an injection context such as a constructor, a factory function, a field initializer, or a function used with `runInInjectionContext`'));
}
}
import {
ElementRef,
assertInInjectionContext,
inject,
} from '@angular/core';
export function injectNativeElement<T extends Element>(): T {
assertInInjectionContext(injectNativeElement);
return inject(ElementRef).nativeElement;
}
- Na
factory
função especificada para umInjectionToken
:
export const FOO = new InjectionToken('FOO', {
factory() {
const value = inject(SOME_PROVIDER);
return ...
},
});
@Component({
providers: [
{
provide: FOO,
useFactory() {
const value = inject(SOME_PROVIDER);
return ...
},
},
]
})
export class FooComponent {}
@Component({})
export class FooComponent {
foo = inject(FOO);
constructor(private ngZone: NgZone = inject(NgZone)) {
const bar = inject(BAR);
}
}
runInInjectionContext
função:import { runInInjectionContext } from '@angular/core';
export class FooComponent {
ngOnInit() {
runInInjectionContext(this.injector, () => {
console.log(
'I can access the NodeInjector using inject()',
inject(ElementRef)
);
})
}
Siga-me no Medium ou Twitter para ler mais sobre Angular e JS!
Christopher Nolan uma vez se arrependeu de ter lido o 'roteiro de Pulp Fiction' de Quentin Tarantino