Асинхронный код в Angular Guard не открывает страницу - PullRequest
0 голосов
/ 15 октября 2018

Настройка проста.У меня есть охранник, который охраняет маршрут.Если свойство пользователя locationSaved === true, то мы хотим разрешить пользователю войти на страницу.

Если первая проверка токена браузера имеет значение false, мы хотим сделать HTTP-запрос, чтобы выяснить, может ли самая последняя версия свойства locationSaved объекта пользователя быть обновлена ​​до true.

Iсделал запрос к серверу, и он вернул true, поэтому я ожидал, что он откроет страницу, но, к сожалению, это не так.Я предполагаю, что это как-то связано с асинхронным запросом, который я сделал на странице, потому что когда я заменяю код запроса сервера простым return true;затем он открывает страницу.

Кто-нибудь знает, как я могу использовать этот асинхронный запрос и перейти на страницу, если сервер возвращает true?

Это мой защитный код.Я настроил так, чтобы он выполнял асинхронный запрос, а сервер возвращал true.Однако он не переходит на страницу.

import { Injectable } from '@angular/core';
import {ActivatedRouteSnapshot, CanActivate} from '@angular/router';
import {AuthenticationService} from './auth.service';
import {Observable} from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class LocationGuardService implements CanActivate {

  constructor(private authService: AuthenticationService) { }

  canActivate(route: ActivatedRouteSnapshot): boolean {
    console.log('entered the guard');
    if (this.authService.isLoggedIn()) {
      if (this.authService.currentUser().user.locationSaved) {
        return true;
      } else {
        this.authService.isLocationSaved()
          .subscribe((status: {saved: boolean}) => {
            console.log('saved', status);
            return status.saved;
          });
      }
    } else {
      return false;
    }
  }
}

1 Ответ

0 голосов
/ 15 октября 2018

Не будет, потому что в блоке else вы ничего не возвращаете.Вместо subscribe ing вы должны иметь map ped для status.saved

Конечно, метод canActivate теперь будет возвращать boolean или Observable<boolean>.Так что вы можете изменить тип возвращаемого значения canActivate.

Это должно работать:

import { Injectable } from '@angular/core';
import { ActivatedRouteSnapshot, CanActivate } from '@angular/router';
import { AuthenticationService } from './auth.service';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';

@Injectable({
  providedIn: 'root'
})
export class LocationGuardService implements CanActivate {

  constructor(private authService: AuthenticationService) { }

  canActivate(route: ActivatedRouteSnapshot): boolean | Observable<boolean> {
    if (this.authService.isLoggedIn()) {
      if (this.authService.currentUser().user.locationSaved) {
        return true;
      } else {
        return this.authService.isLocationSaved()
          .pipe(map(status => status.saved));
      }
    } else {
      return false;
    }
  }
}
...