Search code examples
angularkeycloakkeycloak-angular

Unable to initialize keycloak in angular with Promise with dynamic conf


I would like to call a webservice beforce initializing keycloak frontend component from keycloak-angular library to make keycloakconf dynamic. The backendService.keycloakConfig() webservice returne the correct value but the isInitialized variable is always false.

I think mixing the Promise and the Observable is messing with the initialization.

Here is the code :

import {KeycloakService} from 'keycloak-angular';

import {BackendService} from "./service/backend.service";

export function initializer(keycloak: KeycloakService, backendService: BackendService): () => Promise<any> {

  return (): Promise<any> => {
    return new Promise<void>(async (resolve, reject) => {
      backendService.keycloakConfig()
        .toPromise()
        .then(
          keycloakConfig => {
            try {
              keycloak.init({
                config: keycloakConfig,
                enableBearerInterceptor: true,
                loadUserProfileAtStartUp: false,
                initOptions: {
                  checkLoginIframe: false
                },
                bearerExcludedUrls: ['/assets']
              }).then((isInitialize) => {
                console.log("Initialized keycloak", isInitialize)
              }).catch(reason => {console.log(reason)})
              resolve();
            } catch (error) {
              console.log("error", error)
              reject(error);
            }
          })
    });
  };
}

Solution

  • I answer my own question here :

    I used this library to specify providers order : "ngx-ordered-initializer": "1.0.0"

    in app.module.ts :

        providers: [
        KeycloakService,
        {provide: ORDERED_APP_INITIALIZER, useFactory: initializerConfig, deps: [CommonService], multi: true},
        {provide: ORDERED_APP_INITIALIZER, useFactory: initializer, deps: [KeycloakService, CommonService], multi: true},
        ORDERED_APP_PROVIDER
        },
      ]
    
        export function initializer(keycloak: KeycloakService, commonService: CommonService): () => Promise<any> {
      return (): Promise<any> => {
        return new Promise<void>(async (resolve, reject) => {
          try {
            await keycloak.init({
              config: commonService.customKeyCloakConfig,
              loadUserProfileAtStartUp: false,
              initOptions: {
                checkLoginIframe: false
              },
              enableBearerInterceptor: true,
              bearerExcludedUrls: ['']
            }).then((isInitialize) => {
              console.log("keycloak is initialized : ", isInitialize)
            })
            resolve();
          } catch (error) {
            console.log("error happened during Keycloak initialization : ", error)
            reject(error);
          }
        });
      };
    }
    

    in commonservice :

    customKeyCloakConfig: any;
    
      constructor(private apiService: ApiService, private config: ConfigService) {
      }
    
      public keycloakConfig(){
        return new Promise((resolve, reject) => {
          this.apiService.get<any>(this.config.KEYCLOAK_CONFIG_CUSTOM).subscribe(res => {
            this.customKeyCloakConfig = res;
            resolve(true);
          })
        })
      }