Я новичок в Rx Js, и я был бы признателен, если бы вы посоветовали, какого оператора я могу использовать в моем перехватчике. Мне нужно выполнить asyn c запрос на обновление sh токена аутентификации, если сессия скоро закончится:
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return next.handle(req)
.pipe(
//catchError operator works good, everything's ok here
catchError((error: HttpErrorResponse) => {
if (error instanceof HttpErrorResponse) {
let refreshToken = localStorage.getItem("refreshToken");
if (error && error.status === 401 && refreshToken) {
// 401 errors are most likely going to be because we have an expired token that we need to refresh.
if (this.refreshTokenInProgress) {
// If refreshTokenInProgress is true, we will wait until refreshTokenSubject has a non-null value
// which means the new token is ready and we can retry the request again
return this.refreshTokenSubject.pipe(
filter(result => result !== null),
take(1),
switchMap(() => next.handle(this.authRequest(req)))
);
}
else {
this.refreshTokenInProgress = true;
// Set the refreshTokenSubject to null so that subsequent API calls will wait until the new token has been retrieved
this.refreshTokenSubject.next(null);
return this.backend.auth.refreshToken().pipe(
switchMap((res) => {
if (res) {
//...
return next.handle(this.authRequest(req));
}
else {
this.backend.auth.logOut();
window.location.reload();
}
}),
// When the call to refreshToken completes we reset the refreshTokenInProgress to false
// for the next time the token needs to be refreshed
finalize(() => this.refreshTokenInProgress = false)
);
}
}
else {
this.refreshTokenInProgress = false;
//...
return throwError(error.error);
}
}
}),
//The problem is here, I'm not sure which operator to use to handle successfull response
tap(event => {
if (event instanceof HttpResponse) {
if ((this.backend.auth.getAccessCookieExpireDate())) {
let diffMin = 0;
let diffMs = (Date.parse(this.backend.auth.getAccessCookieExpireDate()) - Date.parse(new Date().toUTCString()));
diffMin = Math.round(((diffMs % 86400000) % 3600000) / 60000);
if (diffMin <= 10) {
//refresh token automatically before it dies
let refreshToken = localStorage.getItem("refreshToken");
if (refreshToken) {
//this async request is not called, can't see it in network
this.backend.auth.refreshToken().pipe(
tap((res) => {
if (res) {
//...
}
else {
this.backend.auth.logOut();
window.location.reload();
}
})
);
}
}
}
}
})
);
}
Так что проблема во второй операторной функции tap()
, она подходит мне, потому что я не нужно возвращать наблюдаемый, но он не позволяет мне выполнить асин c запрос.