reactjsmongodb-stitchreact-context

Need help sending correct payload to update State


I am using MongoDB-Stitch application to create a phonebook app. When I update a user the information gets saved correctly in the database but it won't show on the client until after I refresh the page. I believe the issue is in my reducer with the action.payload._id but I'm not really sure if that is it. Reducer


    case 'updateContact':
        return {
          ...state,
            contacts: state.contacts.map((contact) =>
              contact._id === action.payload._id? action.payload : contact
            ),
            loading: false,
        };```
    Action
    ```const updateContact = async (contactId, contact) => {
            const query = { _id: contactId };
            const update = {
                $set: {
                    contact,
                },
            };
            const options = { upsert: false };
            await items.updateOne(query, update, options);
            dispatch({
                type: 'updateContact',
                payload: [contact, contactId],
            });
        };

My data is stored like this:


    contacts: [
       {
          "_id":"5eb0c9238016c9de09f3d307",
          "contact":{
             "name":"Anne Bonny",
             "email":"anne@bonny.com",
             "phone":"3213231423"
          },
          "owner_id":"5ea89a7e94861451f4c4fe6f"
       },
       {
          "_id":"5eb0c93f8016c9de09f3d308",
          "contact":{
             "name":"Woodes Rogers",
             "email":"woodes@rogers.com",
             "phone":"3217037475"
          },
          "owner_id":"5ea89a7e94861451f4c4fe6f"
       },
       {
          "contact":{
             "name":"john silver",
             "email":"longjohn@silver.com",
             "phone":"9391032314"
          },
          "owner_id":"5ea89a7e94861451f4c4fe6f",
          "_id":"5eb19220a6949dfb5c76e30b"
       },
       {
          "contact":{
             "name":"Charles Vane",
             "email":"charles@vane.com",
             "phone":"3921303921"
          },
          "owner_id":"5ea89a7e94861451f4c4fe6f",
          "_id":"5eb19234a6949dfb5c76e30c"
       }
    ]```

Solution

  • You have sent payload as an array with contactId and contact to reducer, where you are expecting the payload to have _id field in reducer. You probably just need to send the contact and use the _id field from it assuming the contact sent to update contact is of the format

     {
          "_id":"5eb0c93f8016c9de09f3d308",
          "contact":{
             "name":"Woodes Rogers",
             "email":"woodes@rogers.com",
             "phone":"3217037475"
          },
          "owner_id":"5ea89a7e94861451f4c4fe6f"
       },
    

    Change your action to below code to make it work

       const updateContact = async (contactId, contact) => {
            const query = { _id: contactId };
            const update = {
                $set: {
                    contact,
                },
            };
            const options = { upsert: false };
            await items.updateOne(query, update, options);
            dispatch({
                type: 'updateContact',
                payload: contact,
            });
        };
    

    In case your contact object is simply of the below format

      {
             "name":"Woodes Rogers",
             "email":"woodes@rogers.com",
             "phone":"3217037475"
          },
    

    You would need to pass on the contactId separately and update your reducer too like below

       const updateContact = async (contactId, contact) => {
            const query = { _id: contactId };
            const update = {
                $set: {
                    contact,
                },
            };
            const options = { upsert: false };
            await items.updateOne(query, update, options);
            dispatch({
                type: 'updateContact',
                payload: { contact, contactId },
            });
        };
    

    and reducer will be as follows

    case 'updateContact':
        return {
          ...state,
            contacts: state.contacts.map((contact) =>
              contact._id === action.payload.contactId ? { ...contact, contact: action.payload.contact } : contact
            ),
            loading: false,
        };