2017-02-21 21 views
1

私はどこにユーザーをログアウトするアプリケーションがありますか、私はRESTエンドポイントにヒットする必要があります。私は私がここでやろうとしていますかを説明しましょうrxjs `Subject`の` next`を呼び出すとhttp呼び出しがキャンセルされます

@Injectable() 
export class AuthService { 

    private authEvents: Subject<boolean>; 

    constructor(private http: Http) { 
    this.authEvents = new Subject<boolean>(); 
    } 

    login(email: string, password: string): Observable<Response> { 
    const url = 'rest/auth/login'; 
    const body = { 
     email: email, 
     password: password 
    }; 
    return this.http.post(url, body) 
     .do((res: Response) => { 
     localStorage.setItem('currentUser', JSON.stringify(res.json())); 
     this.authEvents.next(true); 
     }); 
    } 

    logout(): Observable<Response> { 
    const url = 'rest/auth/logout'; 
    return this.http.post(url, {}) 
     .do((res: Response) => { 
     localStorage.removeItem('currentUser'); 
     console.log('hereee!'); 
     this.authEvents.next(false); 
     }); 
    } 

    isSignedIn(): boolean { 
    return localStorage.getItem('currentUser') !== null; 
    } 

    get events(): Observable<boolean> { 
    return this.authEvents; 
    } 

} 

:私の角度2のフロントエンドでは、私はこれを処理し、次のサービスを提供しています。ユーザーがクリックボタンをログアウトすると、私は、このコンポーネントでは、次の関数を呼び出し、

ngOnInit() { 
    this.isSignedIn = this.authService.isSignedIn(); 
    this.authService.events.subscribe(() => { 
    this.isSignedIn = this.authService.isSignedIn(); 
    }); 
} 

logout() { 
    this.authService.logout() 
    .subscribe(() => { 
     this.router.navigate(['/home']); 
    }, e => this.handleError(e)); 
} 

問題があることである私が、私はそうのように私のコンポーネントにに加入authEvents主題を持っていますログアウトの呼び出しがまだ完了していなくても、ブラウザは自宅にリダイレクトされます。効果的には、フロントエンドがうまくログアウトしないことがあります。私はここで間違って何をしていますか?

注:httpコールが行われるため、バックエンドのセッションは常にログアウトします。私はObservables(とrxjs一般的に)を使ってこれを達成する方法も見てみたいと思いますが、あまりにも苦労すればPromisesを使うことができます。

+0

主に副作用やデバッグのために.do()を使用してください。また、私は可能な限り熱い観測を避けようとしています。あなたのアプリのデバッグをやや複雑にすることができます。 – DarkNeuron

答えて

0

はのために働いていたものです私:

@olsnが示唆しているように、Subjectを01に変更しました。

しかし、実際にはコンポーネントのhtmlに間違っているように見えました。

<li routerLinkActive="active"><a href="#" (click)="logout(); $event.preventDefault()">Logout</a></li> 

私は$event.preventDefault()(click)イベントで呼び出し、すべてが期待どおりに動作するようですを追加に持っていました。なぜ誰かが私に説明することができれば、それはなぜそうである、それは素晴らしいだろう!

+2

これは 'href ="# "' < - これを削除するためであり、 'preventDefault'は必要ありません。これはアプリケーションが" root "にナビゲートする原因となります - 角度ルータ – olsn

+0

@olsnと干渉しますそれ。 –

2

Subjectの場合、排出量は将来の加入者ではなく、加入者によってのみ受信されます。あなたの人生を楽にするために、BehaviorSubjectを使うことができます。これは将来の加入者にも現在価値を再放出するので、条件。

しかし:厳密にこれ以上イベントで、私はあなたのケースでとにかく使用することをお勧めするものである状態、より多くのではないだろう見て - あなたがイベントを超える状態のパワーを活用することができRxJSであるため。

@Injectable() 
export class AuthService { 

    public currentUser$: BehaviorSubject<IUser> = new BehaviorSubject(null); // initial state is "null" => user is not logged in 
    private isSignedIn$: Observable<boolean> = currentUser$.map(user => Boolean(user)).share(); 

    constructor(private http: Http) { 
    this.authEvents = new Subject<boolean>(); 
    } 

    login(email: string, password: string): Observable<Response> { 
    const url = 'rest/auth/login'; 
    const body = { 
     email: email, 
     password: password 
    }; 
    return this.http.post(url, body) 
     .do((res: Response) => { 
     localStorage.setItem('currentUser', JSON.stringify(res.json())); 
     this.currentUser$.next(res.json()); // will automatically trigger the logged-in state as well 
     }); 
    } 

    logout(): Observable<Response> { 
    const url = 'rest/auth/logout'; 
    return this.http.post(url, {}) 
     .do((res: Response) => { 
     localStorage.removeItem('currentUser'); 
     console.log('hereee!'); 
     this.currentUser$.next(null); // will automatically trigger the logged-in state as well 
     }); 
    } 
} 

コンポーネントで

private desotryed$: Subject<boolean> = new Subject(); 

ngOnInit() { 
    this.authService.isSignedIn$ 
    .takeUntil(this.desotryed$) // to prevent memory leaks through a perpetual subscription 
    .subscribe(isSignedIn => { 
     this.isSignedIn = isSignedIn; 
    }); 
} 

ngOnDestroy() { 
    this.desotryed$.next(true); 
} 

RxJS5のドキュメントがまだBehaviorSubjectを含めていないので、ここでは古いドキュメントへのリンクです:ここではhttps://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/subjects/behaviorsubject.md

+0

これは私が信じる(感謝!)と思うが、私は答えとして掲示した別のアプローチを行った。 "$ event.preventDefault()"をlogout()呼び出しで追加すると動作するようです。あなたはなぜそれが動作するのか教えていただけますか? –

関連する問題