Hooking into the Angular bootstrap process

Post Editor

From this article you'll learn how to use APP_INITIALIZER token and bootstrapModule to hook up into Angular's initialization process.

2 min read
2 comments
post

Hooking into the Angular bootstrap process

From this article you'll learn how to use APP_INITIALIZER token and bootstrapModule to hook up into Angular's initialization process.

post
post
2 min read
2 comments
2 comments

Angular provides several mechanisms to hook into initialization process. This article explores them and shows how they can be used.

APP_BOOTSTRAP_LISTENER
Link to this section

It is possible to register listeners for the Angular bootstrap process. Here is the code where they are called:

<>Copy
private _loadComponent(componentRef: ComponentRef<any>): void { this.attachView(componentRef.hostView); this.tick(); this._rootComponents.push(componentRef); // Get the listeners lazily to prevent DI cycles. const listeners = this._injector.get(APP_BOOTSTRAP_LISTENER, []).concat(this._bootstrapListeners); listeners.forEach((listener) => listener(componentRef)); }

This is the function that Angular calls when instantiating the application. Besides giving insights into how a component is added into the application, it also suggests that for each bootstrapped component Angular calls listeners registered under APP_BOOTSTRAP_LISTENER token and passes bootstrapped component to them.

It means that we can use such hooks to subscribe to the application bootstrap process and perform our initialization logic. For example, here is how Router hooks into to the process and executes some initialization.

Since Angular passes initialized component into the callback, we can get hold of root ComponentRef of the application like this:

<>Copy
import {APP_BOOTSTRAP_LISTENER, ...} from '@angular/core'; @NgModule({ imports: [BrowserModule, ReactiveFormsModule, TasksModule], declarations: [AppComponent, BComponent, AComponent, SComponent, LiteralsComponent], providers: [{ provide: APP_BOOTSTRAP_LISTENER, multi: true, useFactory: () => { return (component: ComponentRef<any>) => { console.log(component.instance.title); } } }], bootstrap: [AppComponent] }) export class AppModule {}

After running into such functionality in the sources I checked the documentation and it’s described as experimental and the following description is provided:

All callbacks provided via this token will be called for every component that is bootstrapped. Signature of the callback: (componentRef: ComponentRef) => void

APP_INITIALIZER
Link to this section

Angular also provides a mechanism to perform some initialization logic before it declares the application as initialized and continues with change detection and template rendering. This is where this initialization takes place:

<>Copy
constructor(@Inject(APP_INITIALIZER) @Optional() appInits: (() => any)[]) { const asyncInitPromises: Promise<any>[] = []; if (appInits) { for (let i = 0; i < appInits.length; i++) { const initResult = appInits[i](); if (isPromise(initResult)) { asyncInitPromises.push(initResult); } } }

So, the same way we did it for the APP_BOOTSTRAP_LISTENER token, we just define APP_INITIALIZER provider and our function will be called. The following example delays Angular initialization for 5 seconds:

<>Copy
{ provide: APP_INITIALIZER, useFactory: () => { return () => { return new Promise((resolve, reject) => { setTimeout(() => { resolve(); }, 5000); }); } }, multi: true }

And you can define multiple APP_INITIALIZER’s like this:

<>Copy
{ provide: APP_INITIALIZER, useFactory: () => { return () => { return new Promise((resolve, reject) => { setTimeout(() => { resolve(); }, 5000); }); } }, multi: true }, { provide: APP_INITIALIZER, useFactory: () => { return () => { return new Promise.resolve(2); } }, multi: true }

BootstrapModule
Link to this section

Another point where you can hook into the application bootstrap process is bootstrapModule method:

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

Here you can get NgModuleRef to the bootstrapped module through which you can access ApplicationRef and ComponentRef.

Comments (2)

authormohanramegowda
6 July 2021

Hi Max, Thanks for the rare and awesome articles.

I need your advise for one of the requirement I have in my Angular application. I have a number of components embedded in various number of parent components and some of the components are lazy loaded by routing. I have a code which has to execute in every component's instantiation or initialization process. I am not allowed to hook this logic in ngOnInit or constructor of the individual components by the requirement because I have a large number of components which has to execute this logic and there are large number of developers working in this project and every developer cannot be asked to hook this from there component's ngOnInit or constructor and this particular logic has to execute for the new components that gets added to the application as well. So is it possible by any chance in Angular to listen to every component's initialization or instantiation in a single place. Could you please advise me on how to fix this problem or point me to any of your articles which already covers this problem.

Thanks in advance, Mohan

authormaxkoretskyi
6 July 2021

So is it possible by any chance in Angular to listen to every component's initialization or instantiation in a single place

Not that I know of. Unless you create them yourself using viewContainer.createComponent(). Or have them all inject some kind of service and call a method on it. But something feels wrong about this requirement. What kind of logic should be applied to all components without them knowing about it?

authormohanramegowda
7 July 2021

Thanks for your response Max. My project is into logistics domain and the application has three common context objects - countryConfigObject, LoggedInUserContextObject and ShippmentObject. This logic is going to execute some strategies by considering some inputs from these context objects to know whether the component can be shown or not shown in the page. Every component in my application has an unique id. So what i am trying to do is find a place which listens to every component's initialization or instantiation and execute this logic.

authormaxkoretskyi
11 July 2021

I see, well, basically I described your options in my previous reply.

Share

About the author

author_image

Max is a self-taught software engineer that believes in fundamental knowledge and hardcore learning. He’s the founder of inDepth.dev community and one of the top users on StackOverflow (70k rep).

author_image

About the author

Max Koretskyi

Max is a self-taught software engineer that believes in fundamental knowledge and hardcore learning. He’s the founder of inDepth.dev community and one of the top users on StackOverflow (70k rep).

About the author

author_image

Max is a self-taught software engineer that believes in fundamental knowledge and hardcore learning. He’s the founder of inDepth.dev community and one of the top users on StackOverflow (70k rep).

Looking for a JS job?
Job logo
Senior Software Engineer, Frontend Angular

JB Hunt

Worldwide
Remote
$115k - $145k
Job logo
Java Fullstack Developer with Angular

Kani Solutions Inc.

United States
Remote
$110k - $130k
Job logo
Angular Developer - Remote, USA

Slipstream IT

United States
Remote
$100k - $127k
Job logo
Senior Angular Developer

Mozym

United States
Remote
$73k - $93k
More jobs
NxAngularCli
NxAngularCli
NxAngularCli

Featured articles

blockchainpost
19 July 202212 min read
An Introduction to Blockchain

Learn the fundamentals of a blockchain starting from first principles. We'll cover hashing, mining, consensus and more. After reading this article, you'll have a solid foundation upon which to explore platforms like Ethereum and Solana.

blockchainpost
19 July 202212 min read
An Introduction to Blockchain

Learn the fundamentals of a blockchain starting from first principles. We'll cover hashing, mining, consensus and more. After reading this article, you'll have a solid foundation upon which to explore platforms like Ethereum and Solana.

Read more
blockchainpostAn Introduction to Blockchain

19 July 2022

12 min read

Learn the fundamentals of a blockchain starting from first principles. We'll cover hashing, mining, consensus and more. After reading this article, you'll have a solid foundation upon which to explore platforms like Ethereum and Solana.

Read more