2017-01-16 13 views
16

@ngrxエフェクトに関する非常に基本的な質問があります:エフェクトの実行中に発生するエラーを将来のエフェクトの実行に影響を与えないように無視する方法はありますか?ngrxはエラー処理に影響を与えます

私の状況は次のとおりです。私はアクション(LOGIN)とそのアクションを聞いているエフェクトを持っています。このエフェクトの内部でエラーが発生した場合は、無視します。このエラーが発生してから2度目にLOGINが送出されると、2回目のエフェクトを実行する必要があります。これを行うには

私の最初の試みでした。予想通り最初の時間は、エラーをスローし、キャッチログイン

@Effect() 
    login$ = this.actions$ 
    .ofType('LOGIN') 
    .flatMap(async() => { 
     console.debug('LOGIN'); 
     // throw an error 
     let x = [];x[0](); 
    }) 
    .catch(err => { 
     console.error('Error at login', err); 
     return Observable.empty(); 
    }); 

を派遣します。しかし、後でLOGINを2回発行すると何も起こりません。その効果は実行されない。

。したがって、私は次のことを試してみました:

.catch(err => { 
     return this.login$; 
    }); 

が、これは無限ループになり...あなたは後で効果の実行を妨げることなく、エラーをキャッチする方法を知っていますか?

+0

を私はngrx知らないが、あなたの代わりに引くの流れにちょうど '.retry()'、おそらくすることができます。 – Gluck

答えて

14

ngrxインフラ、アプリのNgModuleEffectsModule.runを使用してにインポートプロバイダを経由して効果に加入しています。

観測可能なエラーとcatchが空のobervableを返すと、作成されたオブザーバブルは完了し、サブスクライバはサブスクライブされません。つまり、Observable Contractの一部です。それで、あなたはあなたの効果の中でLOGINアクションのそれ以上の処理を見ない理由があります。完了時にその効果は解除され、ngrxインフラストラクチャは再購読しません。

import { Actions, Effect, toPayload } from "@ngrx/effects"; 

@Effect() 
login$ = this.actions$ 
    .ofType('LOGIN') 
    .map(toPayload) 
    .flatMap(payload => Observable 
    .from(Promise.reject('Boom!')) 
    .catch(error => { 
     console.error('Error at login', error); 
     return Observable.empty(); 
    }) 
    }); 

catch平らに空に観察が表示されますインナー観測可能に構成/、効果にマージので、ノーアクション:

通常、あなたは(今mergeMapと呼ばれる)flatMap内のエラー処理を持っているでしょう放出される。

1

これは私が通知または任意のデータを見つけることができませんでした観測には通知されないことにするオプションを処理する方法である:

public listenCampaignValueChanged(emitOnEmpty: boolean = false): Observable<CampaignsModelExt> { 
     var campaignIdSelected$ = this.ngrxStore.select(store => store.appDb.uiState.campaign.campaignSelected) 
     var campaigns$ = this.ngrxStore.select(store => store.msDatabase.sdk.table_campaigns); 
     return campaignIdSelected$ 
      .combineLatest(campaigns$, (campaignId: number, campaigns: List<CampaignsModelExt>) => { 
       return campaigns.find((i_campaign: CampaignsModelExt) => { 
        return i_campaign.getCampaignId() == campaignId; 
       }); 
      }).flatMap(v => (v ? Observable.of(v) : (emitOnEmpty ? Observable.of(v) : Observable.empty()))); 
    } 
2

@Effectストリームはそれ以上のアクションを妨げる、エラーが発生したときにを完了です。

解決策は、使い捨て可能なストリームに切り替えることです。使い捨てストリーム内でエラーが発生した場合は、大文字の@Effectストリームが常に有効なままであり、今後のアクションは引き続き実行されるため、大丈夫です。

このブログの記事では、この技術上の
@Effect() 
login$ = this.actions$ 
    .ofType('LOGIN') 
    .switchMap(action => { 

     // This is the disposable stream! 
     // Errors can safely occur in here without killing the original stream 

     return Rx.Observable.of(action) 
      .map(action => { 
       // Code here that throws an error 
      }) 
      .catch(error => { 
       // You could also return an 'Error' action here instead 
       return Observable.empty(); 
      }); 

    }); 

さらに詳しい情報:The Quest for Meatballs: Continue RxJS Streams When Errors Occur

関連する問題