Immer produce inside rxjs stream can't operate on object

39 views Asked by At

I have a rxjs stream where I want to modify the data moving through the stream with immer's produce.

I combine two observables of an action type:

Action<T, Type extends string = string> is a type of object that represents an event. It has a type property and a payload property.

For context I am using state-adapt for state management and this is where the action type comes from

So i have declared the following stream:

  private addNoteRowToSessionSegmentEffect$ = combineLatest([
    this.segmentStateChangeAction$,
    this.setActiveSessionAction$,
  ]).pipe(
    filter(
      ([noteAction]) =>
      noteAction.payload.action === cellActionsEnum.Enum["TOGGLE-NOTE"]
    ),
    switchMap(([noteAction, sessionAction]) => {
      console.log('session type', typeof sessionAction.payload) // logs 'session type object'
      console.log('session', sessionAction.payload) // logs 'Observable {_subscribe: ƒ}'
      return of(
        produce(sessionAction.payload, draftSession => {
          draftSession.title = noteAction.payload.action;
        })
      );
    }),
    toSource("[FEAT SESSION] add note effect")
  );

The problem is I get the following error:

Uncaught Error: [Immer] produce can only be called on things that are draftable: plain objects, arrays, Map, Set or classes that are marked with '[immerable]: true'. Got '[object Object]'

immer produce works on plain objects but not on observables. I thought that the values inside the switchMap (noteAction and sessionAction) would represent the plain objects of the observable data, but it looks like the observable itself is getting passed into the produce function.

If I console log the value of sessionAction.payload I get Observable {_subscribe: ƒ} instead of a plain object {...}

I am looking for direction on how to get the plain object represented by the observable in the switchMap function.

1

There are 1 answers

0
BizzyBob On BEST ANSWER

If the sectionAction payload is actually an observable, then you need to unwrap it. Something like this should work:

private addNoteRowToSessionSegmentEffect$ = combineLatest([
  this.segmentStateChangeAction$,
  this.setActiveSessionAction$,
]).pipe(
  filter(([noteAction]) => noteAction.payload.action === cellActionsEnum.Enum["TOGGLE-NOTE"]),
  switchMap(([noteAction, sessionAction]) => sessionAction.payload.pipe(
    map(sessionActionPayload => produce(sessionActionPayload, draftSession => {
      draftSession.title = noteAction.payload.action;
    }))
  )),
  toSource("[FEAT SESSION] add note effect")
);

Here is a StackBlitz