Understanding Angular App Initialization Process

Nov 5, 2024

Angular App Initialization Process

Introduction

  • Learn how to hook into the initialization process of an Angular application to execute custom logic.

Why Execute Custom Logic During Initialization?

  • Configuration Resolution: Fetch configuration from the server before rendering components. This config may contain essential information, like server endpoints.
  • Translations: Pre-fetch translations to avoid UI blinking effects and improve user experience.
  • License Checking: Validate user licenses before bootstrapping the application.

How to Execute Custom Logic

  • Use the APP_INITIALIZER injection token in the application root injector.
  • It must be a multi-provider (set multi to true).
  • Provide a function to be executed during the bootstrapping process.

Using Dependency Providers

  • Choose a dependency provider (useValue or useFactory).
  • For the demo, useValue serves as an example, executing a console log to show the initialization.
  • The logic executes when the bootstrapModule method is called in Angular.

Source Code Insights

  • BootstrapModule calls BootstrapModuleFactory, which runs runInitializers from ApplicationInitStatus service.
  • Initializers are stored in appInits and executed before the module bootstrapping.

Returning Values from Initializer

  • Returning simple values like strings is ignored.
  • Returning a promise or an observable will make Angular wait until resolution/completion before proceeding.
  • Infinite observables will block bootstrapping.
  • Use operators like take to complete observables, allowing the application to proceed.

Promise Handling in Angular

  • Angular resolves donePromise upon completion of all promises from initializers.
  • Uses Promise.all to aggregate promises, succeeding when all are resolved.

Building a Real-world Example

  • Feature: Create an initializer module to fetch server config during bootstrapping.
    • Config contains API endpoints for further data fetching by components.
  • Implementation Steps:
    1. Generate a new initializer module.
    2. Clean up unnecessary arrays (imports, declarations), focus on providers.
    3. Use the useFactory provider, creating a function for initialization.
    4. Implement HTTP call logic in a new Angular service (ConfigService).
    5. Inject HttpClientModule and ConfigService.
    6. Create a method to fetch endpoints and handle data with a BehaviorSubject.
    7. Convert the BehaviorSubject to an observable for public access.
    8. Handle errors with fallback URLs.

Angular Service and Initializer Module

  • Access services using the Deps property in the factory function.
  • Fetch endpoints upon application initialization and set up an observable to manage data flow.
  • Test application by injecting the config service in a component and using the fetched API data.

Conclusion

  • Discussed both reactive and non-reactive approaches to handling data in Angular.
  • Emphasized the importance of understanding bootstrapping logic and initializer functions.
  • Encourages exploring other resources for advanced Angular concepts.