1

So I'm creating something like "Trello" clone with react redux nodejs and mongoDB and i have some issue. The problem is when I add a card to a list its not update the redux state, so I will see the card in the list only after a refresh page. (the card added to the DB but not to redux state).

just for more info: boardlists is an array inside the object board from mongo, inside that array there is objects of list, inside each of them there is an array of cards.

here is my code:

REDUCER

const initialState = {
  boardLists: [
    
  ],
};

export default function (state = initialState, action) {
  switch (action.type) {
    case FETCH_ITEMS_BEGIN:
      return {
        ...state,
        loading: true,
        errors: null,
      };
    case FETCH_ITEMS_SUCCESS:
      return {
        ...state,
        loading: false,
        boardLists: action.payload.data.boardLists,
      };
    case FETCH_ITEMS_FAILURE:
      return {
        ...state,
        loading: false,
        errors: action.payload.errors,
        boardLists: [],
      };
    //handless creation of data
    case ADD_LIST:
      return {
        boardLists: [...state.boardLists, action.payload.list],
      };

    case ADD_CARD:
      return {
        boardlists: [...state.boardlists, action.payload.card],
      }

ACTIONS

export const fetchItemsBegin = () => ({
  type: FETCH_ITEMS_BEGIN,
});
export const fetchItemsSuccess = (data) => ({
  type: FETCH_ITEMS_SUCCESS,
  payload: { data },
});
export const fetchItemsFailure = (errors) => ({
  type: FETCH_ITEMS_FAILURE,
  payload: { errors },
});

//dispatched when item needs to be created
export const addList = (list) => {
  return {
    type: ADD_LIST,
    payload: { list },
  };
};

// add card
export const addCard = (card) => {
  return {
    type: ADD_CARD,
    payload: { card }
  };
};

//dispatched when all the lists from board stored in redux store needs to be read
export const getBoardLists = () => {
  return (dispatch) => {
    // function starts
    dispatch(fetchItemsBegin()); // fetching begins
    return http
      .get(`${myUrl}/boards/one`) // req data from server
      .then(({ data }) => {
        console.log(data);

        // if data is found
        dispatch(fetchItemsSuccess(data)); // success
      })
      .catch((error) => dispatch(fetchItemsFailure(error))); //errors
  };
};

COMPONENT THAT HANDLE THE ADD FUNCTION

handleAddCard = () => {
    //add card
    const { text } = this.state;
    const { listID } = this.props;
    const newCard = {
      // _id: uuidv4(),
      text,
    };
    cardService.createCard(newCard, listID);
    this.props.addCard(newCard);
  };

.
.
.
.
.
const mapStateToProps = ({ boardLists, loading, errors }) => ({
  boardLists,
  loading,
  errors,
});

export default connect(mapStateToProps, { addList, addCard, getBoardLists })(ActionButton);
Timo222
  • 57
  • 7
  • What is not working, add card or add list. I think add list should be: `boardLists: [...state.boardLists, ...action.payload.list]`. You can check redux devtools and see if actions are dispatched with correct info and if they cause the changes you want in the state. If anything is wrong you can make your question more specific by providing the information where it goes wrong. – HMR Sep 16 '20 at 08:48
  • add list is working well, its updating the state well. the problem is with add card. – Timo222 Sep 16 '20 at 08:49

1 Answers1

0

It appears you need to update an object in your lists array, and not add the card item to the list array itself.

In the actions:

// add card
export const addCard = (card, listId) => {
  return {
    type: ADD_CARD,
    payload: { listId, card }
  };
};

In the Reducer, you will need to find the list with matching id and add the card to its array e.g.:

case ADD_CARD:
  const {listId, card} = action.payload;
      return {
        ...state,
        boardLists: state.boardLists.map(list => {
          list.cards = list.cards || [];
          return list.id === listId ? {...list, cards: [...list.cards, card]} : list
        }),
      }

This other question on stack overflow could be useful for this part. link

mjbryan10
  • 134
  • 5
  • the add list and add card looks the same.. so if i dispatch in the addlist i did it too in addcard so i dont realy understand where to find the solution – Timo222 Sep 16 '20 at 09:14
  • Sorry, you maybe right there. Though I do notice that you are adding your card to the boardLists array state, the same as the addList action, is that intended? – mjbryan10 Sep 16 '20 at 09:18
  • thats the problem i guess, i dont realy know how to add the card to a list in that boardlists array.. how i do that in redux reducer? – Timo222 Sep 16 '20 at 09:21
  • I think the key is, you are not adding a card to the list array. Instead adding a card to an array in a list object. Is that correct? – mjbryan10 Sep 16 '20 at 09:25
  • You would need to pass the id of the list item with the action, just as you have done to your database. Then in the reducer find the item with matching id, then add card to that objects array field. I will try to update my answer to help. – mjbryan10 Sep 16 '20 at 09:32
  • its whould be great if you give me example – Timo222 Sep 16 '20 at 09:38
  • i saw your edit, the problem is with the "cards" its says not defined – Timo222 Sep 16 '20 at 09:47
  • What does your list object look like, is there a field for cards? – mjbryan10 Sep 16 '20 at 09:50
  • Updated the answer: I just added a line of code that checks for the cards field , if it is a falsey then will give it an empty array. You may have to rename elements to fit your code. – mjbryan10 Sep 16 '20 at 09:59
  • its still not defined the [...cards] – Timo222 Sep 16 '20 at 10:02
  • Cannot read property 'map' of undefined state.boardLists.map – Timo222 Sep 16 '20 at 10:16
  • Just noticed in your code, which I copied to make example, you used both boardLists and boardlists - be careful of casing as these are two different names. I have now corrected answer. – mjbryan10 Sep 16 '20 at 10:24
  • i think i know where is the problem: now if i add a card its dont give me an error but not updating the state like before. i have noticed that when i log "boardLists" from the props i found the array of lists but inside the lists there is allways 0 cards. the node and mongo not adding them to the board, only to the list collection – Timo222 Sep 16 '20 at 10:27