Angular Guard中的异步代码无法打开页面

时间:2018-10-15 17:32:39

标签: angular asynchronous angular-guards

设置很简单。我有一个守卫路线的守卫。如果用户的属性为locationSaved === true,那么我们要允许用户进入页面。

如果浏览器令牌的第一次检查为假,我们想发出一个HTTP请求,以查看用户对象的locationSaved属性的最新版本是否可能更新为true。

我做了服务器请求,它返回了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 :(得分:1)

这不会因为在else块中没有返回任何东西。您应该将subscribe踩到map

,而不是status.saved

当然,canActivate方法现在将返回booleanObservable<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;
    }
  }
}