While attempting to deprecate instances of Angular's "Resolve" class implementation for the preferred functional implementation "ResolveFn", I ran into a perplexing issue.
I have a simple resolver that is preparing my data.
I am receiving this error but unclear on why:
"inject() must be called from an injection context such as a constructor, a factory function, a field initializer, or a function used with EnvironmentInjector#runInContext
."
Code that Errors
import { inject } from '@angular/core';
import { ActivatedRouteSnapshot, ResolveFn } from '@angular/router';
import { PrepareAdHocReportingService } from '@features/reporting/services/prepare-ad-hoc-reporting.service';
import { DashboardsService } from '../dashboards.service';
export const homeDashboardResolver: ResolveFn<void> = async (
route: ActivatedRouteSnapshot
) => {
await inject(PrepareAdHocReportingService).resolve();
const dashboardsService = inject(DashboardsService);
await Promise.all([
dashboardsService.fetchWidgets(),
dashboardsService.getDashboardDetail(route.params.id)
]);
};
The most confusing part is that if I simply move the dashboardsService const up ONE line, it fixes the issue.
Working Code
import { ActivatedRouteSnapshot, ResolveFn } from '@angular/router';
import { PrepareAdHocReportingService } from '@features/reporting/services/prepare-ad-hoc-reporting.service';
import { DashboardsService } from '../dashboards.service';
export const homeDashboardResolver: ResolveFn<void> = async (
route: ActivatedRouteSnapshot
) => {
const dashboardsService = inject(DashboardsService);
await inject(PrepareAdHocReportingService).resolve();
await Promise.all([
dashboardsService.fetchWidgets(),
dashboardsService.getDashboardDetail(route.params.id)
]);
};
Why does simply moving the const up solve this injection issue?
For additional context, both DashboardsService and PrepareAdHocReportingService are injected with "providedIn: 'root'".
@Injectable({ providedIn: 'root' }) export class PrepareAdHocReportingService {}
@Injectable({ providedIn: 'root' }) export class DashboardsService {}
Awaiting a Promise
does effectively exit the injection context.
If you want to run in an injection context, you'll have to use runInInjectorContext
after the await.