NgRX 8で作業している間、同僚と私は効果を実装するときに奇妙なエラーメッセージに頻繁に直面しています。
タイプ 'Observable <unknown>'はタイプ 'Observable <Action>に割り当てることができません| ((... args:any [])=> Observable <Action>) '
タイプの問題に関連しています。メッセージが非常に不特定であり、それが完全な効果を示していることは本当に不愉快です。これは頻繁に発生し、解決が非常に困難です。
問題をすばやく特定するために何かできることがあるのか、または何らかの方法でメッセージを分解できるのか疑問に思っています。ここでは特定の解決策を探しているのではなく、「何が問題なのかをすばやく特定する方法」の手順を探しています。
ありがとう、そして乾杯!
これまでのところ、コメントや回答からのアイデアもあります。
switchMap
パラメータの誤った分解である可能性がありますエラーメッセージを分解するためのトリックを期待しています。
クイックバージョン
コメントアウトcreateEffect(() =>
、
IDE(VSCode)がフラグを立てるエラーを修正し、
add createEffect(() =>
back in。
Alternative-次のような書き換えも機能します
_someEffect$ = createEffect(() => {
return this.actions$.pipe(
...
)
})
_
追加
上記を実行した後にエラーはありませんか?型チェックは正しく機能しており、_Observable<Action>
_にマッピングするか、純粋に副作用として2番目の引数_{ dispatch: false }
_を追加する必要があることを通知します(つまり、アクションをディスパッチしません)。 NgRx Effects Docs を参照してください
古い回答(_@Effect
_を使用する必要はなく、必須ではありません)
私がデバッグで見つけた最も簡単な方法は、_@Effect
_デコレーターを使用してバージョン7の方法で書き込み、完了したらcreateEffect
を使用して再書き込みすることです。
だからデバッグする:
_ navigateToDashboard$ = createEffect(() =>
this.actions$.pipe(
ofType(teamActions.CREATE_SUPERVISOR_GROUP_SUCCESS),
map((action: teamActions.CreateSupervisorGroupSuccess) => action.payload),
map((team: Team) => team.TeamID),
SwitchMap(id => new routerActions.Go({ path: ['/team', id, 'populate'] }))
)
)
_
これは、役に立たないエラーを次のように書き込みます(デコレータの追加、createEffect(() =>
の削除、最後のブラケットの削除)。
_@Effect()
navigateToDashboard$ = this.actions$.pipe(
ofType(teamActions.CREATE_SUPERVISOR_GROUP_SUCCESS),
map((action: teamActions.CreateSupervisorGroupSuccess) => action.payload),
map((team: Team) => team.TeamID),
SwitchMap(id => new routerActions.Go({ path: ['/team', id, 'populate'] }))
)
_
エラーが発生しました
_Cannot find name 'SwitchMap'
_
に続く
_Type 'Go' is not assignable to type 'ObservableInput<any>'
_
これを修正すると
_@Effect()
navigateToDashboard$ = this.actions$.pipe(
ofType(teamActions.CREATE_SUPERVISOR_GROUP_SUCCESS),
map((action: teamActions.CreateSupervisorGroupSuccess) => action.payload),
map((team: Team) => team.TeamID),
switchMap(id => of(new routerActions.Go({ path: ['/team', id, 'populate'] })))
)
_
NgRx 8の条件で書き直します。きれいではありませんが動作します。
私はまったく同じ問題を抱えていましたが、私の場合は中括弧が間違って配置されていて、インポートが欠落していることが原因でした。
これは私がそれをデバッグして解決するためにしたことです。
内部のパイプ可能な関数を個別の関数に分割します。複雑な構文とvscodeからの自動補完ブレースのため、これは私にとって最初のステップです。時々、中括弧が間違った場所にあり、見つけるのが容易ではありません。これにより、デバッグするコードがはるかに小さくなり、vscodeがサブ関数からのこの個別のエラーを強調表示するため、他のほとんどすべての問題(インポートの欠落、不適切な戻り値の型など)も解決されます。
これは私が以前持っていたものです
performLogin$ = createEffect(() =>
this.actions$.pipe(
ofType(performLogin),
mergeMap(() => this.loginService.performLogin().pipe(
map(() => loginSuccess())
)))
);
これを下に変更しました
performLogin$ = createEffect(() =>
this.actions$.pipe(
ofType(performLogin),
mergeMap(() => this.performLogin()),
catchError((error ) => { console.log("HELLO"); return EMPTY})
)
);
performLogin() {
return this.loginService.performLogin()
.pipe(map(() => loginSuccess()));
}
また、私がこのアプローチから得たボーナスは、内側のパイプのcatchErrorブロックがトリガーされないことです(エフェクトの例に従って、それは機能するはずです)。したがって、それを外側のパイプ可能なブロックに含める必要がありました。ここでエラーがキャッチされ、期待どおりに機能します。しかし、なぜそれが機能しないのかを理解しています。
要約すると、ログインサービスは次のことを行います(エラーをスローするか、Observableをtrueで返します)。
//login.service.ts
performLogin() : Observable<boolean> {
throw "Something went wrong";
//return of(true);
}
お役に立てれば。
実際には、createAction
によって作成されたアクションを関数として扱い、それを呼び出してアクションオブジェクトを返す必要があります。これをチェックしてください desc 。したがって、of(addCommentFailed)
はof(addCommentFailed())
になります。
この問題を処理し、公式のngrx 8の例を使用する場合。
loadMovies$ = createEffect(() => this.actions$.pipe(
ofType('[Movies Page] Load Movies'),
mergeMap(() => this.moviesService.getAll()
.pipe(
map(movies => ({ type: '[Movies API] Movies Loaded Success', payload: movies })),
catchError(() => EMPTY)
))
)
);
簡単かつ高速なソリューションは、「任意の」タイプを置くことができます。
loadMovies$: any = createEffect((): any => this.actions$.pipe(
ofType('[Movies Page] Load Movies'),
mergeMap(() => this.moviesService.getAll()
.pipe(
map(movies => ({ type: '[Movies API] Movies Loaded Success', payload: movies })),
catchError(() => EMPTY)
))
)
);
Rxjsオペレーター、オブザーバブルのインポートを忘れないでください。
アクションペイロード-小道具を処理する場合は、アクションタイプを定義します。
ofType<MySuperActions>
または
ofType<ReturnType<typeof myAction>>
ここにimport 'of'演算子がないため、この問題が発生しました
// events.effects.ts
...
getEvents$: Observable<Action> = createEffect(
() => this.actions$.pipe(
ofType(EventsActions.getEvents),
switchMap(action =>
this.eventService.getEvents().pipe(
map(events => EventsActions.getEventsSuccess({ events })),
catchError(error => of(EventsActions.getEventsError({ error })))
)
)
)
);
...
このコード行を上部に追加することで修正しました
// events.effects.ts
import { Observable, of } from 'rxjs';
...
私の場合、rxjsオペレーターの1つの中でlodashオペレーターを使用しました。結局、私は@types/lodash
。後npm i -D @types/lodash
、私の問題は解決しました。
今日同じような問題(同じエラーメッセージ)に遭遇しました。それは、TypeScriptが Array#flatMap
。 Array#map
、 RxJS#map
または明示的に型付けされていない配列。
クラッシュしたコードは次のとおりです。
this.actions$.pipe(
ofType(ActionType),
switchMap((action) => {
return action.cart.flatMap((cartItem: CartItem) => {
if (x) {
return [
ActionCreator1(params1),
ActionCreator2(params2)
];
} else {
return [];
}
}
})
)
だから私は同じエラーメッセージを受け取りました:
タイプ 'Observable <unknown>'はタイプ 'Observable <Action>に割り当てることができません| ((... args:any [])=> Observable <Action>) '
これを修正するには、マッピング関数がAction
の配列を返すことをTypeScriptに通知する必要がありました。
import { Action } from '@ngrx/store';
...
switchMap((action) => {
return action.cart.flatMap((cartItem: CartItem) : Action[] => {
...
また、Action[]
はany
より安全です。