APP_INITIALIZER

Wer kennt es nicht: Die App ist geladen, aber die Daten stehen noch nicht zur Verfügung. Meist wird dies mit dem Elvis-Operator kompensiert, was eine gute Möglichkeit ist, das View-Rendering in den Griff zu bekommen.

Aber was ist mit den Daten in der Business-Logik? Wenn diese nicht zur verfügung stehen, glänzt die Konsole meist in einem tiefen Rot. Aber keine Angst, hierfür gibt es ein Stichwort: APP_INITIALIZER-Providerfunktion.

Um eine Funktion zu registrieren, die beim Initialisieren der Anwendung ausgeführt wird, kannst Du sie als APP_INITIALIZER im @NgModule-Decorator der Anwendung definieren.

import { NgModule, APP_INITIALIZER } from '@angular/core';

@NgModule({
  // Weitere Moduleinstellungen...

  providers: [
    // Andere Provider...

    // Registriere hier Deine APP_INITIALIZER-Funktion:
    {
      provide: APP_INITIALIZER,
      useFactory: () => {
        // Ihre APP_INITIALIZER-Funktion
      },
      deps: [],
      multi: true
    }
  ]
})
export class AppModule { }

Die useFactory-Option des provide-Objekts enthält die Funktion, die beim Initialisieren der Anwendung ausgeführt werden soll. Die deps-Option enthält eine Liste von Abhängigkeiten, die von der APP_INITIALIZER-Funktion verwendet werden. Die multi-Option sollte immer auf true gesetzt werden, damit Angular mehrere APP_INITIALIZER-Funktionen registrieren kann.

Sobald die APP_INITIALIZER-Funktion registriert ist, wird sie von Angular beim Starten der Anwendung aufgerufen. Beachte, dass Angular auf die Fertigstellung der APP_INITIALIZER-Funktion wartet, bevor es fortfährt und die Anwendung startet. Daher lade hier nicht zu viel Funktionalität!

Hinweis: Wenn die APP_INITIALIZER-Funktion asynchron ist und Promises oder Observables zurückgibt, muss Angular auf deren Fertigstellung warten, bevor es fortfährt.

Die multi-Option

Die APP_INITIALIZER-Funktion ist Teil des Angular-Frameworks und wird verwendet, um Funktionen auszuführen, wenn die Anwendung initialisiert wird. Die multi-Option bestimmt, ob die Funktion, die von der APP_INITIALIZER-Funktion aufgerufen wird, nur einmal oder mehrmals ausgeführt werden soll. Wenn die multi-Option auf true festgelegt ist, wird die Funktion jedes Mal ausgeführt, wenn die Anwendung initialisiert wird. Wenn die multi-Option auf false festgelegt ist, wird die Funktion nur einmal ausgeführt, wenn die Anwendung initialisiert wird.

Hier ist ein Beispiel für die Verwendung der multi-Option:

import { APP_INITIALIZER, NgModule } from '@angular/core';

export function someInitializationFunction() {
  // Diese Funktion wird aufgerufen, wenn die Anwendung initialisiert wird
  // Hier kannst Du Code schreiben, der beim Starten der Anwendung ausgeführt werden soll,
  // z.B. das Laden von Konfigurationsdateien oder das Initialisieren von Diensten.
}

@NgModule({
  providers: [
    {
      provide: APP_INITIALIZER,
      useFactory: someInitializationFunction,
      multi: true, // Diese Option gibt an, dass die Funktion mehrmals ausgeführt werden soll
      deps: []
    }
  ]
})
export class AppModule {}

In diesem Beispiel wird die someInitializationFunction-Funktion von der APP_INITIALIZER-Funktion aufgerufen, wenn die Anwendung initialisiert wird. Die multi-Option ist auf true festgelegt, sodass die someInitializationFunction-Funktion jedes Mal ausgeführt wird, wenn die Anwendung initialisiert wird.

Hier ist ein Beispiel für die Verwendung der APP_INITIALIZER-Funktion und der multi-Option in Angular mit der multi-Option auf false festgelegt:

import { APP_INITIALIZER, NgModule } from '@angular/core';

export function someInitializationFunction() {
  // Diese Funktion wird aufgerufen, wenn die Anwendung initialisiert wird
  // Hier kannst Du Code schreiben, der beim Starten der Anwendung ausgeführt werden soll,
  // z.B. das Laden von Konfigurationsdateien oder das Initialisieren von Diensten.
}

@NgModule({
  providers: [
    {
      provide: APP_INITIALIZER,
      useFactory: someInitializationFunction,
      multi: false, // Diese Option gibt an, dass die Funktion nur einmal ausgeführt werden soll
      deps: []
    }
  ]
})
export class AppModule {}

In diesem Beispiel wird die someInitializationFunction-Funktion von der APP_INITIALIZER-Funktion aufgerufen, wenn die Anwendung initialisiert wird. Die multi-Option ist auf false festgelegt, sodass die someInitializationFunction-Funktion nur einmal ausgeführt wird, wenn die Anwendung initialisiert wird.

Die deps-Option

Die deps-Option in der APP_INITIALIZER-Funktion dient dazu, Abhängigkeiten für die Initialisierungsfunktion anzugeben. Diese Abhängigkeiten werden dann von Angular beim Start der Anwendung automatisch geladen und können von der Initialisierungsfunktion verwendet werden.

Achtung: Wenn eine der in deps angegebenen Abhängigkeiten geändert wird, wird die Initialisierungsfunktion erneut ausgeführt, um sicherzustellen, dass die Anwendung immer auf dem neuesten Stand ist.

Hier ist ein Beispiel für die Verwendung der deps-Option in der APP_INITIALIZER-Funktion:

import { APP_INITIALIZER, NgModule } from '@angular/core';
import { ConfigService } from './config.service';

export function initConfig(config: ConfigService) {
  return () => config.load();
}

@NgModule({
  providers: [
    ConfigService,
    {
      provide: APP_INITIALIZER,
      useFactory: initConfig,
      deps: [ConfigService],
      multi: true
    }
  ]
})
export class AppModule {}

In diesem Beispiel wird die initConfig-Funktion als APP_INITIALIZER-Provider bereitgestellt. Die deps-Option enthält ein Array mit der ConfigService, die als Abhängigkeit für die Initialisierungsfunktion benötigt wird. Wenn die ConfigService geändert wird, wird die initConfig-Funktion erneut ausgeführt.

Ein Beispiel für die Verwendung der deps-Option mit einem Dienst wäre folgendermaßen:

import { APP_INITIALIZER, Injectable } from '@angular/core';

@Injectable()
export class MyService {
  // ...
}

export function appInit(myService: MyService) {
  return () => {
    // Nutze hier myService, um die Initialisierung durchzuführen.
  };
}

@NgModule({
  providers: [
    MyService,
    {
      provide: APP_INITIALIZER,
      useFactory: appInit,
      deps: [MyService],
      multi: true
    }
  ]
})
export class AppModule {
  // ...
}

In diesem Beispiel wird der MyService dem appInit-Faktor über die deps-Option zur Verfügung gestellt. Der appInit-Faktor kann dann auf den MyService zugreifen und ihn innerhalb seiner Routine verwenden.

Ein Beispiel für die Verwendung der deps-Option mit dem HttpClient von Angular wäre folgendermaßen:

import { APP_INITIALIZER, Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';

@Injectable()
export class MyService {
  // ...
}

export function appInit(myService: MyService, http: HttpClient) {
  return () => {
    // Nutze hier myService und http, um die Initialisierung durchzuführen.
  };
}

@NgModule({
  imports: [
    HttpClientModule
  ],
  providers: [
    MyService,
    {
      provide: APP_INITIALIZER,
      useFactory: appInit,
      deps: [MyService, HttpClient],
      multi: true
    }
  ]
})
export class AppModule {
  // ...

In diesem Beispiel wird der MyService und der HttpClient dem appInit-Faktor über die deps-Option zur Verfügung gestellt. Der appInit-Faktor kann dann auf den MyService und den HttpClient zugreifen und sie innerhalb seiner Routine verwenden. Beachten Sie, dass das HttpClientModule auch importiert werden muss, um den HttpClient nutzen zu können.

Ich hoffe, dieser Beitrag hilft dir! Lass es mich wissen, wenn du weitere Fragen hast.