Search code examples
angularngrxngrx-storengrx-entity

NGRX entity: How to assign action.payload to state property in UpsertOne


I have a reducer in entity state. How do I assign action.payload.Message to saveMessage.msg while performing upsertOne on UPSERT_Message_SUCCESS action.

 export interface MessageState extends EntityState<Message> {
  // additional entities state properties
    selectedMessageId: number | null;
    loaded: boolean;
    loading: boolean;
  saveMessage?: {
    loaded: boolean;
    loading: boolean;
    msg?: Message;
  };
}

export const adapter: EntityAdapter<Message> = createEntityAdapter<Message>({
  selectId: (msg: Message) => msg.messageId,

});

export const initialState: MessageState = adapter.getInitialState({
  // additional entity state properties
    selectedMessageId: null,
    loaded: false,
    loading: false,
  saveMessage: {
    loaded: false,
    loading: false
  },

});

export function reducer(state = initialState, action: MessageActionsUnion): MessageState {
  switch (action.type) {

    case MessageActionTypes.UPSERT_MessageS_SUCCESS: {
      return adapter.upsertMany(action.payload.Messages, { ...state, loaded: true, loading: false });
    }



    case MessageActionTypes.UPSERT_Message: {
      return { ...state,loading: true, loaded:false };
    }


   //assign action.payload.message to saveMessage.msg

    case MessageActionTypes.UPSERT_Message_SUCCESS: {
   return  adapter.upsertOne(action.payload.saveMessageHeader, {...state,loaded:true,loading:false});

  // return {
  //   ...state,
  //   saveMessage: {
  //     loading: false,
  //     loaded: true,
  //     msgHeader: action.payload.saveMessageHeader
  //   }
 // };
}
    case MessageActionTypes.UPSERT_Message_FAIL: {
      return { ...state };
    }



    default: {
      return state;
    }
  }
}

The corresponding action call signature is below:

export class SaveMessageSuccess implements Action {
  readonly type = MessageActionTypes.SAVE_MESSAGE_SUCCESS;
  constructor(public payload:  {saveMessage:partial <Message> }) {
  }
}

Solution

  • upsertOne doesn't allow a Partial<Entity> but expects an entity T.

    In you case changing the action creator to the following should do the trick:

    export class SaveMessageSuccess implements Action {
      readonly type = MessageActionTypes.SAVE_MESSAGE_SUCCESS;
      constructor(public payload:  {saveMessage: Message}) {
      }
    }
    

    @ngrx/entity docs