2017-07-17 5 views
0

私は、Apollo-Clientを使って、GraphQLサーバに対してクエリと突然変異を作成しています。 Apolloには独自のエラー処理があるので、takeUntil関数を実装してクエリ呼び出しと私の突然変異をキャンセルするのはずっと難しくなります。アポロを使用してRxJsのtakeUntil()関数をapollo-clientで使用する

、ここに私の変異は次のようになります。

export const languageTimeZoneEpic = (action$) => { 
    return action$.ofType(CHANGE_LANGUAGE) 
    .mergeMap(action => client.mutate({ 
     mutation: languageMutation, 
     variables: { id: action.id, language: action.selected_language } 
    }).then(result => changeLanguageFulfilled(result)) 
     .catch(error => changeLanguageError(error)) 
); 
}; 

私の変異は問題なく行われ、エラーがある場合、それをキャッチします。 ここでの問題は、以下の例のようにtakeUntil()関数を追加すると、私の関数はまったく機能しなくなります。

export const languageTimeZoneEpic = (action$) => { 
    return action$.ofType(CHANGE_LANGUAGE) 
    .mergeMap(action => client.mutate({ 
     mutation: languageMutation, 
     variables: { id: action.id, language: action.selected_language } 
    }).then(result => changeLanguageFulfilled(result)) 
     .catch(error => changeLanguageError(error)) 
).takeUntil("END_LANGUAGE"); 
}; 

私は、独自のエラー処理を持つクライアントを使用する場合でも、takeUntil()機能を使用できるようにする方法があった場合、私は思っていました。

*突然変異が完了する前に別のアクションをディスパッチすると、ここのtakeUntil()が呼び出されます。

答えて

1

takeUntilは、引数として文字列を受け付けません、ありがとうございました。代わりに、最初のnext'd値をシグナルとして使用して、ObservableがサブスクライブするObservableを期待します。

Reduxの、観察可能な99.9%だけRxJSので、すべての事業者が再来、観測可能で提供する唯一の演算子であるofTypeため除く再来/アクションについて何を知らない、です - 残りはイン建てRxJSです。

隔離の問題もあります。 mergeMapの外側にtakeUntilを置くと、特定のapolloクライアントクライアントだけでなく、Epic全体がキャンセルされます。代わりにmergeMapに配置する必要があります。プロミスを扱っているため、Observable.fromを使用してラップしてください。

export const languageTimeZoneEpic = (action$) => { 
    return action$.ofType(CHANGE_LANGUAGE) 
    .mergeMap(action => 
     Observable.from(
     client.mutate({ 
      mutation: languageMutation, 
      variables: { id: action.id, language: action.selected_language } 
     }) 
     .then(result => changeLanguageFulfilled(result)) 
     .catch(error => changeLanguageError(error)) 
    ) 
     .takeUntil(action$.ofType('END_LANGUAGE')) 
    ); 
}; 

しかし、場違い間違いなく、このように約束thencatchを使用して - あなたが約束して作業する場合、私はReduxの-、観察に対してお勧めかもしれません。 redux-observableを使用している場合、他の選択肢がない場合(たとえば、apollo-client APIを制御しないなど)、通常はPromisesでのみ動作します。これらのケースでは、私は通常Observableとしてできるだけ早くそれらをラップし、残りは通常のRxJSです。

export const languageTimeZoneEpic = (action$) => { 
    return action$.ofType(CHANGE_LANGUAGE) 
    .mergeMap(action => 
     Observable.from(client.mutate({ 
     mutation: languageMutation, 
     variables: { id: action.id, language: action.selected_language } 
     })) 
     .map(result => changeLanguageFulfilled(result)) 
     .catch(error => Observable.of(
      changeLanguageError(error) 
     )) 
     .takeUntil(action$.ofType('END_LANGUAGE')) 
    ); 
}; 

これは、時にはそれがより冗長だ意味が、これはReduxの観察可能に従うことが、あなたのコードは非常に非常に難しいことができますので、ほとんどそれは約束のcatchを使用していないことです。 "このプロミスキャッチかオブザーバブルキャッチか?"もちろん、これはちょうど私の意見:)


である私は、アポロ・クライアントは本当の約束が解約されないため、突然変異をキャンセル実際の方法がないと仮定しました。このコードは、プロミスの結果を技術的に無視するのではなく、本当にそれをキャンセルする(不可能)だけです。

+0

>分離の問題もあります。 takeUntilをmergeMapの外側に置くと、特定のapollo-clientクライアントだけでなく、Epic全体がキャンセルされます。 私の一部はそれを知っていましたが、 'mergeMap'の後に' takeUntil'を置くとjusteは私にエラーを与えました。私はそれを試してみると思っていました。 – petithomme

+0

はいApollo-clientは、今のところ、突然変異をそれ自身でキャンセルする方法はありません。私はあなたの2番目の例で行ったことが好きですが、あなたが言ったように、変異を取り消すことはありません**しかし、**結果を無視するだけです。私は少なくともユーザーに変更を表示せずに、彼が最後に行った操作をレンダリングするように実装しようとするかもしれません。答えてくれてありがとう ! – petithomme

+0

@petithomme大歓迎です! – jayphelps

関連する問題