hugger
hugger

Reputation: 488

Redux adding an object to an array not working for the first record only

When adding an object to an array with Redux, for some reason adding the first record would not work.

I would get the following error:

TypeError: Invalid attempt to spread non-iterable instance. in order to be iterable, non-array objects must have a [Symbolic.iterator]()method.

With this code:

case POST_COMMENTS_ADD:
  return {
    ...state,
    comments: [...state.comments, action.newItem[0]],
    lastKey: null,
    noData: null,
  };

I would like to understand why this approach was not working when I feel like it should have been.

Here is how I managed it to add (first record without an error - all subsequent adds worked fine with the initial code)

case POST_COMMENTS_ADD:
  return {
    ...state,
    comments: !state.comments ? [action.newItem[0]] : [...state.comments, action.newItem[0]],
    lastKey: null,
    noData: null,
  };

The fix works, but I'd like to see where I went wrong with the first approach.

Here is my entire reducer:

  import {
    POST_COMMENTS_FETCH_SUCCESS,
    POST_COMMENTS_NO_DATA,
    UNMOUNT_POST_COMMENTS,
    POST_COMMENTS_ADD,
  } from '../actions/types';

  const INITIAL_STATE = {
    comments: [],
  };

  export default (state = INITIAL_STATE, action) => {
    switch (action.type) {
      case POST_COMMENTS_FETCH_SUCCESS:
        return {comments: action.payload, lastKey: action.key, noData: null};
      case POST_COMMENTS_NO_DATA:
        return {comments: null, lastKey: null, noData: true};
      case POST_COMMENTS_ADD:
        return {
          ...state,
          comments: !state.comments ? [action.newItem[0]] : [action.newItem[0], ...state.comments],
          lastKey: null,
          noData: null,
        };
      case UNMOUNT_POST_COMMENTS:
        return {comments: null, noData: null};
      default:
        return state;
    }
  };

Upvotes: 0

Views: 536

Answers (1)

Subin Sebastian
Subin Sebastian

Reputation: 10997

Your default initialState seems fine, But we can see that in couple of actions(POST_COMMENTS_NO_DATA and UNMOUNT_POST_COMMENTS) you are setting comments as null. Instead, it should be set as []. So even though state is initialized with comments as [] it is later changed as null as either of these actions are fired before POST_COMMENTS_ADD

case POST_COMMENTS_NO_DATA:
        return {comments: [], lastKey: null, noData: true};
  case UNMOUNT_POST_COMMENTS:
        return {comments: [], noData: null};

Upvotes: 3

Related Questions