Accessing root Angular 2 injector instance globally

Here is another take for Angular 9.

Open the JavaScript console on the page of your Angular application that is not in the production node.

Find the <app-root> on the page:

root = document.querySelector("app-root");

Get the injector. The ng() helper is a global that is available if the app is in development mode:

injector = ng.getInjector("app-root");

Injector would allow you to get services by their class name. Unfortunately, I do not know if or how Angular service classes are available through the window namespace.

So our next attempt is to get services from the components of the already visible elements on the page.

appComponent = ng.getComponent(root)

This way you get access to any AppComponent variables e.g. "UserService" your app might have.

appComponent.userService
UserService {http: HttpService, userSubject: BehaviorSubject}

Now you can call the service from the console:

appComponent.userService.userSubject.value.userEmail
[email protected]

You can also access components that are not the application root, and get access to services bound to them. First we need to navigate to the page where the component appears. This will trigger the actual transition in the UI.

await appComponent.router.navigate(["/another-page"])

Now you can get hold of any visible component by its tag name:

elem = document.querySelector("app-my-component")
component = ng.getComponent(elem)

And you can see its services:

MyComponent(envService, http, sanitizer);

And you can poke them, with all your user tokens, sessions, etc. in place:

component.envService.getConfigValue()

In Angular v.4.x.x the root injector is located on the PlatformRef. You can access it like this:

import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';

// create a platform    
let platform = platformBrowserDynamic();

// save reference to the global object
window['rootInjector'] = platform.injector;

// boostrap application
platform.bootstrapModule(AppModule);

Or inside any component like this:

export class AppComponent {
  constructor(platform: PlatformRef) {
      console.log(platform.injector);

But the root injector is pretty useless. It contains mostly compiler and platform specific data and helpers:

[
  "InjectionToken Platform ID",
  "PlatformRef_",
  "PlatformRef",
  "Reflector",
  "ReflectorReader",
  "TestabilityRegistry",
  "Console",
  "InjectionToken compilerOptions",
  "CompilerFactory",
  "InjectionToken Platform Initializer",
  "PlatformLocation",
  "InjectionToken DocumentToken",
  "InjectionToken Platform: browserDynamic",
  "InjectionToken Platform: coreDynamic",
  "InjectionToken Platform: core"
]

You're probably looking for AppModule injector which you can get like this:

platform.bootstrapModule(AppModule).then((module) => {
  window['rootInjector'] = module.injector;
});

You can extract ApplicationRef or root ComponentRef from it:

platform.bootstrapModule(AppModule).then((module) => {
  let applicationRef = module.injector.get(ApplicationRef);
  let rootComponentRef = applicationRef.components[0];
});

Also, if Angular is running in the development mode, you can get either AppModule or lazy loaded NgModule injector like this:

ng.probe($0).injector.view.root.ngModule

You must set it into a service after bootstrapping the application:

export var applicationInjector: Injector;

bootstrap([AppComponent]).then((componentRef: ComponentRef) => {
  applicationInjector = componentRef.injector;
});

Then you can import it into other parts of your application:

import {applicationInjector} from './bootstrap';

See this question for more details:

  • Good way to secure multiple Angular 2 components

Edit

You can inject the ApplicationRef into components and have access to the root injector through it:

@Component({
  (...)
})
export class SomeComponent {
  constructor(private app:ApplicationRef) {
    var rootInjector = app.injector;
  }
}

You need to leverage dependency injection to get it.