Angular - How to initialize auth interceptor before APP_INITIALIZER service is initialized?
I have an Angular application with an auth interceptor that adds a JWT to each request.
auth.interceptor.ts
gets the user instance and JWT from the user.service
as soon as it is available:
@Injectable()
export class AuthInterceptor implements HttpInterceptor {
currentUser: User;
constructor(private userService: UserService) {
this.userService.user$
.subscribe(currentUser => this.currentUser = currentUser);
}
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
if (this.currentUser && this.currentUser.token) {
const requestWithAuthHeader = req.clone({
headers: req.headers.set('authorization', 'Bearer ' + this.currentUser.token)
});
return next.handle(requestWithAuthHeader);
}
}
}
I have another service, that gets the user
object from user.service
, and sends an HTTP request as soon as user
is available:
@Injectable({ providedIn: 'root' })
export class SettingsService {
constructor(private http: HttpClient, private userService: UserService) {
this.userService.user$.pipe(
filter(user => !!user && !!user.token), // wait until user is not null
).subscribe(() => this.fetchAppSettingsFromServer()); // sends an Http request
}
}
SettingsService
is loaded very early in the app, using the APP_INITIALIZER
in the app.module:
{ provide: APP_INITIALIZER, useFactory: () => () => null, deps: [SettingsService], multi: true },
This leads to a situaltion where SettingsService
gets the user
object early and sends an http request very quickly before the auth.interceptor has a chance to be initialized, and the result is an http request without an added JWT.
To solve this, I added a small delay
in sending the request, to allow the auth.interceptor enough time to be initialized, and it works fine:
@Injectable({ providedIn: 'root' })
export class SettingsService {
constructor(private http: HttpClient, private userService: UserService) {
this.userService.user$.pipe(
filter(user => !!user && !!user.token), // wait until user is not null
delay(100) // wait until auth.interceptor is initialized
).subscribe(() => this.fetchAppSettings()); // must connect before app loads to support eaarly loading of data before component is diplayed
}
// ...
}
But this doesn't seem like the best solution, and there must be a more elegant way to do it. Any ideas how to make auth.interceptor get ready before SettingsService
sends out a request?
from Recent Questions - Stack Overflow https://ift.tt/HwqVg7e
https://ift.tt/2seQpNE
Comments
Post a Comment