Hook into Angular’s Initialization Process

Written by dormoshe | Published 2017/04/29
Tech Story Tags: angular | angularjs | web-development | front-end-development | javascript

TLDRvia the TL;DR App

This article originally appeared on dormoshe.io

Sometimes you need to hook into internal processes. Sometimes you need to run your code before the application is being loaded. Sometimes you need to configure parts of the application before the page is being rendered. Sometimes you want to suspend the initialization until some restriction is being done. In Angular v4 you can do this with the APP_INITIALIZER token.

Live example

In this article, we will understand what is an Injection Token, what is the APP_INITIALIZER and how to use it to hook into the initialization process. In addition, we will see a source code of the core module that runs this functionality and we will cover three of the Angular usages of this feature.

Let’s start…

Injection Token

InjectionToken is an improved version of Angular v2 OpaqueToken (one of the changes in v4). It allows us to create string-based tokens without running into any collisions in the dependency injection mechanism. Creating an InjectionToken is easy.

APP_INITIALIZER Token

APP_INITIALIZER is one of the injection tokens of Angular. This token is still experimental. When you are using APP_INITIALIZER, Angular will execute the provided function when the app is initialized. Angular will delay the initialization if the function returns a promise until the promise resolution. This means the application can be initialized without quite so much latency and you can also use the existing services and framework features.

An Example

This example was written based on Tour of Heroes project. The definition of the NgModule.providers array looks like:

APP_INITIALIZER module providers

So there are two functions called in the initialization process — onAppInit1, onAppInit2. Here are the functions’ implementations:

APP_INITIALIZER providers factory functions

As you can see, each of the functions returns a promise. The Angular initialization process will continue until all the initialization promises will be resolved. Here is the video of the run as part of the Tour of Heroes project:

Tour of heroes — run

The initializers ran by Angular concurrently and the loading has been delayed until the last resolving. So you can put your business logic in the providers. It can be some configurations or loading of remote resource and set of the response in an angular service.

Internals

Angular declares the APP_INITIALIZER token and runs the provided functions in a service — ApplicationInitStatus. Here is part of the code:

App-initializer file source code

In the first line, the token is declared. The service constructor takes the functions that provided, if there are, runs them and pushes the returned promises to an array.

Application-init-status service — part I

Then angular runs all the promises concurrently by Promise.all. The _done property will stay false until all the promises resolved.

Application-init-status service — part II

The source code can be found here.

How Angular uses the APP_INITIALIZER?

Angular uses the APP_INITIALIZER token to initialize some of its implementations on the application initialization time. Here are 3 of the usages.

ng.probe

Having the reference of a DOM element, you have the ability to inspect the state of the component it is located in. You can do this by using ng.probe and put the DOM element as an argument like ng.probe($0).

Angular uses the APP_INITIALIZER token to configure and initialize the ng.prob before the app initializes, so the ng.prob will be available on demand.

The source code can be found here.

Web Workers

Web Workers provide a simple means for web content to run scripts in background threads. The worker thread can perform tasks without interfering with the user interface. Angular is decoupled from the DOM via a higher level API so we can use web worker concept.

Angular uses the APP_INITIALIZER in order to set up the DOM adapter before using it, so the DOM API calls will not be done on the real browser DOM. This adapter is required to log error messages using the traditional js console object. Other methods — of browser DOM API — all throw exception as the DOM is not accessible directly in web worker context.

The source code can be found here.

Routing

To initialize the router properly, Angular needs to do two major steps:

  • Starts the navigation in the APP_INITIALIZER to block the bootstrap if a resolver or a guard is executed asynchronously.
  • Runs activation in the BOOTSTRAP_LISTENER. To do that, Angular utilizes the afterPreactivation hook that provided by the router.

The router navigation starts reach to the point when the preactivation is done, and then it pauses. It waits for the hook to be resolved. And then resolves it in a bootstrap listener.

The source code can be found here.

Conclusion

Tokens are widely-used in Angular for injecting values. You can use them for your needs like configurations. Angular supplies convenient way to hook into the application initialization process. When you choose to fit in this process, do it after consideration because it suspends the application from being loaded.

You can follow me on dormoshe.io or Twitter to read more about Angular, JavaScript and web development.


Published by HackerNoon on 2017/04/29