Почему невозможно вернуть Obeservable.of(false) в блоке catch в методе canActivate?
Я использую функцию canActivate для защиты некоторых маршрутов (администратор). Для этого случая я использую authGuard
класс / функции:
Проблема в том, когда я пытаюсь вернуть наблюдаемое логическое значение как: return Observable.of(false);
не работает должным образом и выдает следующее сообщение об ошибке:
Аргумент типа '(err: any) => Наблюдаемый | Observable'нельзя назначить параметру типа'(err: any, catch: Observable) => ObservableInput'. Тип 'Наблюдаемый | Observable "нельзя назначить типу" ObservableInput ". Тип Observable не может быть назначен типу ObservableInput. Тип "Наблюдаемый" не может быть назначен типу "ArrayLike". Свойство length отсутствует в типе Observable.
Я искал и нашел вид этой проблемы, но не совсем то же самое. И предоставленная подсказка / решение было использовать .throw(err);
Когда я изменяю возврат на: return Observable.throw(err);
, то ошибка исчезает, но не возвращается false
как и положено для того, чтобы защитить мой маршрут.
Я считаю, что это проблема типа и т. Д., Но я просто не могу это исправить, так что я продолжаю возвращаться observable.of(false)
canActivate( next: ActivatedRouteSnapshot, state: RouterStateSnapshot ): Observable<boolean> | Promise<boolean> | boolean {
return this.userService.getAdminAuth()
.map( (res) => {
if ( res === true) {
return true;
} else {
......
return false;
}
})
.catch( (err) => {
if ( err.status === 403 ) {
console.log(`403: ${err.status}`);
return this.userService.refreshToken()
.map( (res) => {
console.log(`Res RefreshToken: ${res}`);
});
}
return Observable.of(false); // protect route!
});
}
Функции в user.service.ts:
....
isAdminAuthenticated = false;
public getAdminAuth() {
console.log('Saved token: ' + localStorage.getItem('ac_token') );
if ( this.isAdminAuthenticated === true ) {
return Observable.of(true);
} else {
return this.http.get(
'URL', {
headers: new HttpHeaders({"Accept": "application/json"}),
withCredentials: true,
observe: "response"
}
)
.map((res) => {
if (res.status === 200) {
this.isAdminAuthenticated = true;
return true;
} else {
return false;
}
}, (err) => {
console.log('Error: ' + err);
return false;
});
}
}
refreshToken() {
return this.http.get(
'URL',
{
headers: new HttpHeaders(
{
"Accept": "application/json",
"Authorization" : "Bearer " + localStorage.getItem('ac_token')
}
),
withCredentials: true,
observe: "response"
}
)
}
С другой стороны, если я изменю refreshToken
функция для:
refreshToken() {
return this._http.get(
'URL',
{
headers: new HttpHeaders(
{
"Accept": "application/json",
"Authorization" : "Bearer " + localStorage.getItem('ac_token')
}
),
withCredentials: true,
observe: "response"
}
).map( (res) => {
console.log(`Res: ${JSON.stringify(res)}` );
}), (err) => {
console.log(`Err: ${JSON.stringify(err)}` );
};
}
Тогда ошибка говорит:
ОШИБКА в src/app/admin.guard.ts(38,9): ошибка TS2322: тип "Наблюдаемый" не может быть назначен типу "логический | Обещание | Наблюдаемое. Тип "Наблюдаемый" не может быть назначен типу "Наблюдаемый". Тип 'логическое значение | {}'нельзя назначить типу' логический '. Тип "{}" нельзя назначить типу "логический". src/app/service.guard.ts: ошибка TS2339: Свойство 'map' не существует для типа '(err: any) => boolean'.
1 ответ
Потому что вы должны использовать return Observable.throw(false)
, of
это успех, throw
это ошибка.