Home > other >  Problem mapping one action to another in ngrx effect
Problem mapping one action to another in ngrx effect

Time:07-28

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
                      )
                    })
                  )
                );
            }
          })
        )
      )
    )
  );
  • Related