Whenever I add my Keycloak app initializer to my angular 17 project it returns undefined.
Keycloak is running in a docker container locally.
The administrator console is working and I have set up my realm and clients. It is also working with my backend for the application without issue.
But the implementation for the frontend seems to be tricky.
Specific versions:
- Angular v17
- Angular-Keycloak v17
- Keycloak-js v23
Stack trace
ERROR undefined core.mjs:6531:22
Angular 32
handleError
_callAndReportToErrorHandler
invoke
run
runOutsideAngular
_callAndReportToErrorHandler
invoke
onInvoke
invoke
run
scheduleResolveOrReject
invokeTask
onInvokeTask
invokeTask
onInvokeTask
invokeTask
runTask
drainMicroTaskQueue
invokeTask
invokeTask
globalCallback
globalZoneAwareCallback
(Async: EventListener.handleEvent)
customScheduleGlobal
scheduleTask
onScheduleTask
scheduleTask
onScheduleTask
scheduleTask
scheduleTask
scheduleEventTask
makeAddListener
set
processCallback keycloak.mjs:772
processInit keycloak.mjs:261
Angular 23
invoke
onInvoke
invoke
run
scheduleResolveOrReject
invokeTask
onInvokeTask
invokeTask
onInvokeTask
invokeTask
runTask
drainMicroTaskQueue
(Async: promise callback)
nativeScheduleMicroTask
scheduleMicroTask
scheduleTask
onScheduleTask
scheduleTask
onScheduleTask
scheduleTask
scheduleTask
scheduleMicroTask
scheduleResolveOrReject
then
init keycloak.mjs:322
Angular 5
init
__async
ZoneAwarePromise
__async
init
keycloakInitializer keycloak.initializer.ts:19
ZoneAwarePromise Angular
keycloakInitializer keycloak.initializer.ts:18
Angular 11
runInitializers
internalCreateApplication
_callAndReportToErrorHandler
internalCreateApplication
invoke
onInvoke
invoke
run
run
internalCreateApplication
bootstrapApplication
<anonymous> main.ts:6
Keycloak instance
{
"_keycloakEvents$": {
"closed": false,
"currentObservers": [],
"observers": [],
"isStopped": false,
"hasError": false,
"thrownError": null
},
"_enableBearerInterceptor": true,
"_loadUserProfileAtStartUp": true,
"_authorizationHeaderName": "Authorization",
"_bearerPrefix": "Bearer ",
"_excludedUrls": [
{
"urlPattern": {},
"httpMethods": []
}
],
"_silentRefresh": false,
"_updateMinValidity": 20,
"_instance": {
"didInitialize": true,
"authenticated": false,
"silentCheckSsoFallback": true,
"enableLogging": false,
"messageReceiveTimeout": 10000,
"responseMode": "fragment",
"responseType": "code",
"flow": "standard",
"clientId": "client-1",
"authServerUrl": "https://localhost:8543",
"realm": "realm-1",
"endpoints": {},
"timeSkew": 0,
"tokenTimeoutHandle": null
}
}
app.config.ts
import { APP_INITIALIZER, ApplicationConfig, importProvidersFrom, inject } from "@angular/core";
import {provideRouter, withComponentInputBinding, withRouterConfig} from '@angular/router';
import { routes } from './app.routes';
import { provideAnimationsAsync } from '@angular/platform-browser/animations/async';
import {TranslateLoader, TranslateModule} from "@ngx-translate/core";
import {TranslateHttpLoader} from "@ngx-translate/http-loader";
import { HttpClient, provideHttpClient, withFetch, withInterceptors } from "@angular/common/http";
import {SystemLanguage} from "./core/enums/system-language.enum";
import { MAT_DATE_LOCALE } from "@angular/material/core";
import { KeycloakAngularModule, KeycloakBearerInterceptor, KeycloakService } from "keycloak-angular";
import { keycloakInitializer } from "@root/core/features/authentication/initializers/keycloak.initializer";
export function HttpLoaderFactory(http: HttpClient): TranslateHttpLoader {
return new TranslateHttpLoader(http);
}
export const appConfig: ApplicationConfig = {
providers: [
{ provide: MAT_DATE_LOCALE, useValue: 'da-DK' },
provideRouter(routes, withComponentInputBinding(), withRouterConfig({ paramsInheritanceStrategy: "always" })),
provideHttpClient(
withFetch(),
withInterceptors([
(req, next) => {
return inject(KeycloakBearerInterceptor).intercept(req, { handle: r => next(r) });
}
]),
),
{
provide: APP_INITIALIZER,
useFactory: keycloakInitializer,
multi: true,
deps: [KeycloakService]
},
KeycloakService,
KeycloakAngularModule,
importProvidersFrom(
KeycloakService,
KeycloakAngularModule,
TranslateModule.forRoot({
defaultLanguage: SystemLanguage.English,
useDefaultLang: true,
loader: {
provide: TranslateLoader,
useFactory: HttpLoaderFactory,
deps: [HttpClient]
}
}),
),
{
provide: KeycloakBearerInterceptor,
useClass: KeycloakBearerInterceptor
},
provideAnimationsAsync(),
]
};
keycloak.initializer.ts
import { KeycloakOptions, KeycloakService } from "keycloak-angular";
export function keycloakInitializer(keycloak: KeycloakService) {
console.log(keycloak);
const options: KeycloakOptions = {
config: {
realm: "realm-1",
url: "https://localhost:8543",
clientId: "client-1"
},
loadUserProfileAtStartUp: true,
initOptions: {
onLoad: "check-sso",
checkLoginIframe: false,
},
enableBearerInterceptor: true,
bearerExcludedUrls: [".readonly"],
};
return () => {
return new Promise<boolean>((resolve, reject) => {
keycloak.init(options).then((value) => {
console.log(value);
resolve(true);
}).catch((error) => {
console.log(error);
reject(error);
});
})
};
}
I have tried a bunch of different ways of importing and providing keycloak-angular and its services.
There was no change, still undefined.
Whenever I add my Keycloak app initializer to my angular 17 project it returns undefined.
Keycloak is running in a docker container locally.
The administrator console is working and I have set up my realm and clients. It is also working with my backend for the application without issue.
But the implementation for the frontend seems to be tricky.
Specific versions:
- Angular v17
- Angular-Keycloak v17
- Keycloak-js v23
Stack trace
ERROR undefined core.mjs:6531:22
Angular 32
handleError
_callAndReportToErrorHandler
invoke
run
runOutsideAngular
_callAndReportToErrorHandler
invoke
onInvoke
invoke
run
scheduleResolveOrReject
invokeTask
onInvokeTask
invokeTask
onInvokeTask
invokeTask
runTask
drainMicroTaskQueue
invokeTask
invokeTask
globalCallback
globalZoneAwareCallback
(Async: EventListener.handleEvent)
customScheduleGlobal
scheduleTask
onScheduleTask
scheduleTask
onScheduleTask
scheduleTask
scheduleTask
scheduleEventTask
makeAddListener
set
processCallback keycloak.mjs:772
processInit keycloak.mjs:261
Angular 23
invoke
onInvoke
invoke
run
scheduleResolveOrReject
invokeTask
onInvokeTask
invokeTask
onInvokeTask
invokeTask
runTask
drainMicroTaskQueue
(Async: promise callback)
nativeScheduleMicroTask
scheduleMicroTask
scheduleTask
onScheduleTask
scheduleTask
onScheduleTask
scheduleTask
scheduleTask
scheduleMicroTask
scheduleResolveOrReject
then
init keycloak.mjs:322
Angular 5
init
__async
ZoneAwarePromise
__async
init
keycloakInitializer keycloak.initializer.ts:19
ZoneAwarePromise Angular
keycloakInitializer keycloak.initializer.ts:18
Angular 11
runInitializers
internalCreateApplication
_callAndReportToErrorHandler
internalCreateApplication
invoke
onInvoke
invoke
run
run
internalCreateApplication
bootstrapApplication
<anonymous> main.ts:6
Keycloak instance
{
"_keycloakEvents$": {
"closed": false,
"currentObservers": [],
"observers": [],
"isStopped": false,
"hasError": false,
"thrownError": null
},
"_enableBearerInterceptor": true,
"_loadUserProfileAtStartUp": true,
"_authorizationHeaderName": "Authorization",
"_bearerPrefix": "Bearer ",
"_excludedUrls": [
{
"urlPattern": {},
"httpMethods": []
}
],
"_silentRefresh": false,
"_updateMinValidity": 20,
"_instance": {
"didInitialize": true,
"authenticated": false,
"silentCheckSsoFallback": true,
"enableLogging": false,
"messageReceiveTimeout": 10000,
"responseMode": "fragment",
"responseType": "code",
"flow": "standard",
"clientId": "client-1",
"authServerUrl": "https://localhost:8543",
"realm": "realm-1",
"endpoints": {},
"timeSkew": 0,
"tokenTimeoutHandle": null
}
}
app.config.ts
import { APP_INITIALIZER, ApplicationConfig, importProvidersFrom, inject } from "@angular/core";
import {provideRouter, withComponentInputBinding, withRouterConfig} from '@angular/router';
import { routes } from './app.routes';
import { provideAnimationsAsync } from '@angular/platform-browser/animations/async';
import {TranslateLoader, TranslateModule} from "@ngx-translate/core";
import {TranslateHttpLoader} from "@ngx-translate/http-loader";
import { HttpClient, provideHttpClient, withFetch, withInterceptors } from "@angular/common/http";
import {SystemLanguage} from "./core/enums/system-language.enum";
import { MAT_DATE_LOCALE } from "@angular/material/core";
import { KeycloakAngularModule, KeycloakBearerInterceptor, KeycloakService } from "keycloak-angular";
import { keycloakInitializer } from "@root/core/features/authentication/initializers/keycloak.initializer";
export function HttpLoaderFactory(http: HttpClient): TranslateHttpLoader {
return new TranslateHttpLoader(http);
}
export const appConfig: ApplicationConfig = {
providers: [
{ provide: MAT_DATE_LOCALE, useValue: 'da-DK' },
provideRouter(routes, withComponentInputBinding(), withRouterConfig({ paramsInheritanceStrategy: "always" })),
provideHttpClient(
withFetch(),
withInterceptors([
(req, next) => {
return inject(KeycloakBearerInterceptor).intercept(req, { handle: r => next(r) });
}
]),
),
{
provide: APP_INITIALIZER,
useFactory: keycloakInitializer,
multi: true,
deps: [KeycloakService]
},
KeycloakService,
KeycloakAngularModule,
importProvidersFrom(
KeycloakService,
KeycloakAngularModule,
TranslateModule.forRoot({
defaultLanguage: SystemLanguage.English,
useDefaultLang: true,
loader: {
provide: TranslateLoader,
useFactory: HttpLoaderFactory,
deps: [HttpClient]
}
}),
),
{
provide: KeycloakBearerInterceptor,
useClass: KeycloakBearerInterceptor
},
provideAnimationsAsync(),
]
};
keycloak.initializer.ts
import { KeycloakOptions, KeycloakService } from "keycloak-angular";
export function keycloakInitializer(keycloak: KeycloakService) {
console.log(keycloak);
const options: KeycloakOptions = {
config: {
realm: "realm-1",
url: "https://localhost:8543",
clientId: "client-1"
},
loadUserProfileAtStartUp: true,
initOptions: {
onLoad: "check-sso",
checkLoginIframe: false,
},
enableBearerInterceptor: true,
bearerExcludedUrls: ["https://www.googleapis/auth/spreadsheets.readonly"],
};
return () => {
return new Promise<boolean>((resolve, reject) => {
keycloak.init(options).then((value) => {
console.log(value);
resolve(true);
}).catch((error) => {
console.log(error);
reject(error);
});
})
};
}
I have tried a bunch of different ways of importing and providing keycloak-angular and its services.
There was no change, still undefined.
Share Improve this question edited Mar 21 at 19:05 Alexander Vestergaard Eriksen asked Mar 17 at 20:58 Alexander Vestergaard EriksenAlexander Vestergaard Eriksen 1712 silver badges10 bronze badges1 Answer
Reset to default 0Wild guess, but could you do it exactly like how it is given in the docs.
import { KeycloakOptions, KeycloakService } from "keycloak-angular";
export function keycloakInitializer(keycloak: KeycloakService) {
const options: KeycloakOptions = {
config: {
realm: "realm-1",
url: "https://localhost:8543",
clientId: "client-1"
},
loadUserProfileAtStartUp: true,
initOptions: {
onLoad: "check-sso",
checkLoginIframe: false,
},
enableBearerInterceptor: true,
bearerExcludedUrls: ["https://www.googleapis/auth/spreadsheets.readonly"],
};
return () => {
return keycloak.init(options);
};
}
Also please add a single provider KeycloakService
to the configuration.
export const appConfig: ApplicationConfig = {
providers: [
{ provide: MAT_DATE_LOCALE, useValue: 'da-DK' },
provideRouter(routes, withComponentInputBinding(), withRouterConfig({ paramsInheritanceStrategy: "always" })),
provideHttpClient(
withFetch(),
withInterceptors([
(req, next) => {
return inject(KeycloakBearerInterceptor).intercept(req, { handle: r => next(r) });
}
]),
),
{
provide: APP_INITIALIZER,
useFactory: keycloakInitializer,
multi: true,
deps: [KeycloakService]
},
KeycloakService, // <- notice!
KeycloakBearerInterceptor,
importProvidersFrom(
TranslateModule.forRoot({
defaultLanguage: SystemLanguage.English,
useDefaultLang: true,
loader: {
provide: TranslateLoader,
useFactory: HttpLoaderFactory,
deps: [HttpClient]
}
}),
),
{
provide: HTTP_INTERCEPTORS,
useClass: KeycloakBearerInterceptor,
multi: true,
deps: [KeycloakService]
},
provideAnimationsAsync(),
]
};