I'm having a problem mapping one action to another.
This works fine:
loadUserUnitScore = createEffect(() =>
this.actions$.pipe(
ofType(userActions.loadUserUnitScore),
mergeMap((scoreParams) =>
this.databaseService.getUserScoreForEntity(scoreParams).pipe(
map((userUnitScore) =>
userActions.userUnitScoreLoaded({
userUnitScore: userUnitScore as UserUnitScore,
})
)
)
)
)
);
I need to get some additional properties here which I can't get to work.
loadUserUnitScore = createEffect(() =>
this.actions$.pipe(
ofType(userActions.loadUserUnitScore),
mergeMap((scoreParams) =>
this.databaseService.getUserScoreForEntity(scoreParams).pipe(
map((userUnitScore) => {
if ('thematicUnit' in userUnitScore) {
return userActions.userUnitScoreLoaded({ userUnitScore });
} else {
// This line causes an error
return this.structureService
.getUnit((userUnitScore as DraftUserUnitScore).unitId)
.pipe(
map((unit) =>
userActions.userUnitScoreLoaded({
userUnitScore: buildUserUnitScoreFromDraft(
userUnitScore as DraftUserUnitScore,
unit
)
})
)
);
}
})
)
)
)
);
(property) userUnitScoreLoaded: (props: { userUnitScore: UserUnitScore; }) => { userUnitScore: UserUnitScore; } & TypedAction<"[User] User unit score loaded"> Type 'Observable<({ userUnitScore: UserUnitScore; } & TypedAction<"[User] User unit score loaded">) | Observable<{ userUnitScore: UserUnitScore; } & TypedAction<...>>>' is not assignable to type 'EffectResult'. Type 'Observable<({ userUnitScore: UserUnitScore; } & TypedAction<"[User] User unit score loaded">) | Observable<{ userUnitScore: UserUnitScore; } & TypedAction<...>>>' is not assignable to type 'Observable'. Type '({ userUnitScore: UserUnitScore; } & TypedAction<"[User] User unit score loaded">) | Observable<{ userUnitScore: UserUnitScore; } & TypedAction<"[User] User unit score loaded">>' is not assignable to type 'Action'. Property 'type' is missing in type 'Observable<{ userUnitScore: UserUnitScore; } & TypedAction<"[User] User unit score loaded">>' but required in type 'Action'.ts(2322)
I don't see what I'm doing wrong. The first part is getting something from the DB and mapping it to a new action. With the new code it adds another step also resulting in an action right? I don't see how it is different/wrong.
CodePudding user response:
The problem is that this.structureService.getUnit
seems to return an Observable
but you are inside a map
which expects a non-Observable
return type.
You should try to change map
to switchMap
. Also since switchMap
expects an Observable
but userActions.userUnitScoreLoaded
does not return one, we can wrap it in of()
.
loadUserUnitScore = createEffect(() =>
this.actions$.pipe(
ofType(userActions.loadUserUnitScore),
mergeMap((scoreParams) =>
this.databaseService.getUserScoreForEntity(scoreParams).pipe(
switchMap((userUnitScore) => {
// ^ instead of map
if ('thematicUnit' in userUnitScore) {
return of(userActions.userUnitScoreLoaded({ userUnitScore }));
// ^of() to make this an Observable
} else {
return this.structureService
.getUnit((userUnitScore as DraftUserUnitScore).unitId)
.pipe(
map((unit) =>
userActions.userUnitScoreLoaded({
userUnitScore: buildUserUnitScoreFromDraft(
userUnitScore as DraftUserUnitScore,
unit
)
})
)
);
}
})
)
)
)
);