私は、ngrxストアがそれを処理するはずの効果に対するアクションをディスパッチしないという問題を抱えています。
ディスパッチを試みるコンポーネントは次のとおりです。
signin() {
this.formStatus.submitted = true;
if (this.formStatus.form.valid) {
this.store.dispatch(new StandardSigninAction(this.formStatus.form.value.credentials));
}
}
アクション:
export const ActionTypes = {
STANDARD_SIGNIN: type('[Session] Standard Signin'),
LOAD_PERSONAL_INFO: type('[Session] Load Personal Info'),
LOAD_USER_ACCOUNT: type('[Session] Load User Account'),
RELOAD_PERSONAL_INFO: type('[Session] Reload Personal Info'),
CLEAR_USER_ACCOUNT: type('[Session] Clear User Account')
};
export class StandardSigninAction implements Action {
type = ActionTypes.STANDARD_SIGNIN;
constructor(public payload: Credentials) {
}
}
...
export type Actions
= StandardSigninAction
| LoadPersonalInfoAction
| ClearUserAccountAction
| ReloadPersonalInfoAction
| LoadUserAccountAction;
の効果:
@Effect()
standardSignin$: Observable<Action> = this.actions$
.ofType(session.ActionTypes.STANDARD_SIGNIN)
.map((action: StandardSigninAction) => action.payload)
.switchMap((credentials: Credentials) =>
this.sessionSigninService.signin(credentials)
.map(sessionToken => {
return new LoadPersonalInfoAction(sessionToken);
})
);
デバッグでは、コンポーネントがdispatchメソッドを呼び出すことがわかります。コンストラクターのブレークポイントにヒットしたため、StandardSigninAction
が実際にインスタンス化されていることも確認できます。
しかし standardSignin$
エフェクトは呼び出されません...
呼び出されない効果を引き起こす可能性があるものは何ですか?
ストア内で行われていることをデバッグするにはどうすればよいですか?
誰か助けてくれますか?
追伸私はインポートで次のように上記の効果を実行します:
EffectsModule.run(SessionEffects),
編集:これは私のSessionSigninService.signinメソッドです(Observableを返します)
signin(credentials: Credentials) {
const headers = new Headers({'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'});
const options = new RequestOptions({headers: headers});
const body = 'username=' + credentials.username + '&password=' + credentials.password;
return this.http.post(this.urls.AUTHENTICATION.SIGNIN, body, options).map(res => res.headers.get('x-auth-token'));
}
これは決定的な答えになるわけではありませんが、うまくいけば、役に立つでしょう。
始める前に:
@ngrx
パッケージの最新バージョンを使用していることを確認してください(Angularのバージョンに適しています)。まだ行っていない場合は、 Store
の実装 を見てください。そうすれば、何が間違っているのかについて、経験に基づいた推測を行うことができます。 Store
はかなり軽いことに注意してください。オブザーバブル(状態をソースとして使用)とオブザーバー(ディスパッチャーに任せる)の両方です。
store.dispatch
を見ると、 store.next
のエイリアスであることがわかります。これは next
でDispatcher
を呼び出します=。
だから呼び出す:
this.store.dispatch(new StandardSigninAction(this.formStatus.form.value.credentials));
ディスパッチャから発行されたアクションが表示されるだけです。
エフェクトに挿入される Actions
observableもかなり軽いです。 Dispatcher
をソースとして使用する単なるオブザーバブルです。
エフェクトを流れるアクションを見るために、これを置き換えることができます:
@Effect()
standardSignin$: Observable<Action> = this.actions$
.ofType(session.ActionTypes.STANDARD_SIGNIN)
これとともに:
@Effect()
standardSignin$: Observable<Action> = this.actions$
.do((action) => console.log(`Received ${action.type}`))
.filter((action) => action.type === session.ActionTypes.STANDARD_SIGNIN)
ofType
は演算子ではありません。メソッドであるため、do
ベースのロギングを追加するには、filter
に置き換える必要があります。
ロギングが適切に行われている場合、アクションを受け取っている場合、エフェクトの実装に何らかの問題があります(または、アクションタイプの文字列/定数が、あなたが思っているものではなく、何かが一致していない可能性があります)。
エフェクトがディスパッチされたアクションを受け取っていない場合、最も可能性の高い説明は、store
をディスパッチしているStandardSigninAction
が、エフェクトが使用しているstore
と同じではないことです。つまり、DIの問題があります。
その場合は、動作していると言う他のSessionEffects
と異なるものを調べる必要があります。 (少なくとも、何か機能するものがあり、実験を始めるのに適しています。)それらは別のモジュールからディスパッチされていますか? StandardSigninAction
をディスパッチするモジュールは機能モジュールですか?
作業中のSessionEffects
の1つをハックして、ディスパッチされたアクションをStandardSigninAction
に置き換えた場合はどうなりますか?その後、エフェクトは実行されますか?
この回答の最後にある質問は、私が答えたい質問ではないことに注意してください。それらはあなた自身に尋ね、調査するべき質問です。
ストアのストリームは、未処理のエラーまたは-おそらくもっとわかりにくい-.catch
は、物事を続けるために新しいObservableを再送信することなく、実際にストリームを強制終了します。
たとえば、これはストリームを殺します:
this.actions$
.ofType('FETCH')
.map(a => a.payload)
.switchMap(query => this.apiService.fetch$(query)
.map(result => ({ type: 'SUCCESS', payload: result }))
.catch(err => console.log(`oops: ${err}`))) // <- breaks stream!
しかし、これは物事を生き続けます:
this.actions$
.ofType('FETCH')
.map(a => a.payload)
.switchMap(query => this.apiService.fetch$(query)
.map(result => ({ type: 'SUCCESS', payload: result }))
.catch(e => Observable.of({ type: 'FAIL', payload: e}))) // re-emit
これは、rxjs Observable btwにも当てはまります。これは、複数のオブザーバーにブロードキャストするときに考慮することが特に重要です(ngrxストアが内部Subject
を使用して内部的に行うように)。
私はngrxの新しいバージョン(7.4.0)を使用しているため、cartanの提案は次のとおりです。
.do((action) => console.log(`Received ${action.type}`))
あるべき...
... = this.actions.pipe(
tap((action) => console.log(`Received ${action.type}`)),
...
そして最後に、次のような新しいエフェクトエクスポートをモジュールに追加するのを忘れていたことがわかりました。
EffectsModule.forRoot([AuthEffects, ViewEffects]), // was missing the ', ViewEffects'