2017-07-03 71 views
1

我想复制angular-realworld-example-app,但我遇到了一个我不明白的错误。 (我正在使用RxJS 5.4.0和Angular 4.2.5)。ReplaySubject是不是一个功能

我的路线“登陆”具有保护“无验证卫士”,以检查用户是否已经登录。只有“非登录”用户可以在“登录”。警卫检查用户是否登录,并否定答案(bool =>!bool)以确定用户是否可以通过。

User.service.ts:

import { Injectable } from '@angular/core'; 
import { Http } from '@angular/http'; 
import { Observable } from 'rxjs/Observable'; 
import { BehaviorSubject } from 'rxjs/BehaviorSubject'; 
import { ReplaySubject } from 'rxjs/ReplaySubject'; 
import 'rxjs/add/operator/distinctUntilChanged'; 
import 'rxjs/add/operator/map'; 
import 'rxjs/add/operator/catch'; 


import { ApiService } from './api.service'; 
import { JwtService } from './jwt.service'; 
import { User } from '../models/user.model'; 


@Injectable() 
export class UserService { 
    private currentUserSubject = new BehaviorSubject<User>(new User()); 
    public currentUser = this.currentUserSubject.asObservable().distinctUntilChanged(); 

    private isAuthenticatedSubject = new ReplaySubject<boolean>(1); 
    public isAuthenticated = this.isAuthenticatedSubject.asObservable(); 

    constructor (
     private apiService: ApiService, 
     private http: Http, 
     private jwtService: JwtService 
    ) {} 

    // Verify JWT in localstorage with server & load user's info. 
    // This runs once on application startup. 
    populate() { // THIS IS CALLED IN APP.COMPONENT 
     // If JWT detected, attempt to get & store user's info 
     if (this.jwtService.getToken()) { 
      this.apiService.get('/user') 
       .subscribe(
        data => this.setAuth(data.user), 
        err => this.purgeAuth() 
       ); 
     } else { 
      // Remove any potential remnants of previous auth states 
      this.purgeAuth(); 
     } 
    } 

    setAuth(user: User) { 
     // Save JWT sent from server in localstorage 
     this.jwtService.saveToken(user.token); 
     // Set current user data into observable 
     this.currentUserSubject.next(user); 
     // Set isAuthenticated to true 
     this.isAuthenticatedSubject.next(true); 
    } 

    purgeAuth() { 
     // Remove JWT from localstorage 
     this.jwtService.destroyToken(); 
     // Set current user to an empty object 
     this.currentUserSubject.next(new User()); 
     // Set auth status to false 
     this.isAuthenticatedSubject.next(false); 
    } 

    attemptAuth(type, credentials): Observable<User> { 
     const route = (type === 'login') ? '/login' : ''; 
     return this.apiService.post('/user' + route, {user: credentials}) 
      .map(
       data => { 
        this.setAuth(data.user); 
        return data; 
       } 
      ); 
    } 

    getCurrentUser(): User { 
     return this.currentUserSubject.value; 
    } 
} 

无AUTH-guard.service.ts:

import { Injectable } from '@angular/core'; 
import { ActivatedRouteSnapshot, CanActivate, Router, RouterStateSnapshot } from '@angular/router'; 
import { Observable } from 'rxjs/Rx'; 
import 'rxjs/add/operator/map'; 

import { UserService } from '../services/user.service'; 

@Injectable() 
export class NoAuthGuard implements CanActivate { 
    constructor(
     private router: Router, 
     private userService: UserService 
    ) {} 

    canActivate(
     route: ActivatedRouteSnapshot, 
     state: RouterStateSnapshot 
    ): Observable<boolean> { 

     return this.userService.isAuthenticated.take(1).map(bool => !bool); 
    } 
} 

尽管更新我进口,我还收到一个错误采取的是不是一个函数Getting boolean value from ReplaySubject<boolean> asObservable

Error: Uncaught (in promise): TypeError: this.userService.isAuthenticated.take is not a function 
TypeError: this.userService.isAuthenticated.take is not a function 

类似,但不重复

+3

take是一个像地图一样的运算符。它必须被导入。 – cgTag

+0

谢谢,这导致我在正确的方向+1 – Moshe

回答

2

我们可以通过两种方式来解决它。

import 'rxjs/add/operator/take'; 

这很可能是进口的特定运营商为你服务。

import { Observable } from 'rxjs'; 

我喜欢上面的语句,因为它提供了你需要在可观察到的,而不是一个单独的import语句为运营商所有运营商。

+0

导入全库会减慢我的应用程序启动时,通过单独导入它们,我更加意识到我的用法。谢谢 – Moshe