2016-11-05 37 views
7

Ben ettik got @ ngrx/mağaza ve çalışma etkiler ince, ancak, sadece orada (etkileri) API çağrıları aa çok olacak ve gerçekleştirdikleriyle getiri varsa Bir 401 hatası Kullanıcıyı giriş sayfasına yönlendirmeliyim. Benim sorunum: Bunu her bir etkide kontrol etmek istemiyorum, aynı şey için bir ton ekstra kod olurdu.Eğik 2,

Numune etkisi

@Effect() getMe$ = this.actions$ 
    .ofType(GET_ME) 
    .map(action => action.payload) 
    .switchMap(payload => this.userService.me() 
     .map(res => ({ type: GET_ME_SUCCESS, payload: res })) 
     .catch(() => Observable.of({ type: GET_ME_FAILURE })) 
    ); 

userService.me()

me(): Observable<User> { 
    return this.apiService.get(`/auth/me`); 
} 

apiService.get()

: s örneğin böyle bir kod var diyelim
get(endpoint: string): Observable<any> { 
    return this.http.get(`${this.base}${endpoint}`, this.options()) 
    .map(res => res.json()); 
} 

Bu, gayet iyi çalışır, ancak API, numaralı duruma döndüğünde durumu nasıl ele alacağından emin değilim. Bu durumda kullanıcıyı global olarak nereye yönlendirmeliyim? Bu dava için bir eylem oluşturmalı mıyım? O eylemi nereye göndereyim o zaman? Yoksa tamamen yanlış mı yapıyorum?

Doğru yönde herhangi bir yardım için teşekkür ederiz!

cevap

12

Http'dan gönderilen hatalar, sunucudan alınan hatalardan kaynaklanıyorsa, status özelliği (HTTP durum koduna ayarlanmış) içerir.

bunu HTTP tabanlı hizmet başarısızlık eylemlere hata durumunu eklerseniz: onlar 401 hatası içeriyorsa

@Effect() getMe$ = this.actions$ 
    .ofType(GET_ME) 
    .map(action => action.payload) 
    .switchMap(payload => this.userService.me() 
     .map(res => ({ type: GET_ME_SUCCESS, payload: res })) 
     .catch(error => Observable.of({ 
      type: GET_ME_FAILURE, 
      payload: { errorStatus: error.status } 
     })) 
    ); 

Ardından tüm eylemlerin bakar ve yönlendiren bir genel amaçlı etkisini yazabilirsiniz :

import { go } from '@ngrx/router-store'; 
... 

@Effect() errorStatus401$ = this.actions$ 
    .map(action => action.payload) 
    .filter(payload => payload && payload.errorStatus === 401) 
    .map(payload => go(['/login'])); 
:

@Effect() errorStatus401$ = this.actions$ 
    .map(action => action.payload) 
    .filter(payload => payload && payload.errorStatus === 401) 
    .switchMap(payload => { 
     this.router.navigate(['/login']); 
     return Observable.empty(); 
    }); 

Veya, @ngrx/router-store kullanıyorsanız Eğer navigasyona önce gerçekleştirmek isteyen ek eylemler varsa

, sen concat kullanarak birden eylemleri yayabilir:

@Effect() errorStatus401$ = this.actions$ 
    .map(action => action.payload) 
    .filter(payload => payload && payload.errorStatus === 401) 
    .switchMap(payload => Observable.concat({ type: 'CLEAR_TOKEN' }, go(['/login']))); 
+0

Tamamdır, iş gibi görünüyor, teşekkürler! Sakıncası yoksa sadece bir soru daha: navigasyondan önce başka bir eylem (CLEAR_TOKEN) aramak için bir yol var mı? Gözlemler benim için gerçekten yeni. :) – Andrew

+1

Evet, bu mümkün. Cevabı güncelledim. – cartant