Search code examples
node.jsreactjsmongodbmongoose

how to update records after drag and drop


I am using react-sortable-hoc to drag/drop and reorder items. When I do this though I want to update the database (node.js and mongodb).

Firstly, I have changed it to be a functional component which is why my syntax looks a bit different to the example.

const onSortEnd = ({ oldIndex, newIndex }) => {

    setItems((items) => arrayMove(items, oldIndex, newIndex));

    const newArray = arrayMove(items, oldIndex, newIndex);

    async function makePatchRequest() {
      const config = {
        method: "patch",
        url: "http://localhost:8000/api/admin/faq/order",
        headers: { Authorization: "Bearer " + auth.token },
        data: {
          order: newArray,
        },
      };

      let res = await axios(config, { order: newArray });

    }
    makePatchRequest();
  };

I am sending the new array to the backend with everything in the order after the drag and drop. The issue is that I don't really know what to do with it on the backend. Do I need to delete all records and then loop over the array and insert new records? I initially wanted to loop over the records and update them but it isn't actually doing anything, probably because the code is wrong or my logic is wrong because all it is doing is overwriting with the exact same data because all that has changed is the order of the array, not the actual id or _id in the array.

exports.faqSort = async (req, res) => {
  const { order } = req.body;
  console.log(order);

  await order.map((o) => {
    Faq.update({ _id: o._id }, { $set: { id: o.id } });
  });
};

This is the array when the page loads:

[
  {
    _id: '5ed273049b268308302cb1fb',
    question: 'question 1',
    answer: 'answer 1',
    id: 1,
    __v: 0
  },
  {
    _id: '5ed273439b268308302cb1fd',
    question: 'question 2',
    answer: 'answer 2',
    id: 2,
    __v: 0
  },
  {
    _id: '5ed276129b268308302cb1ff',
    question: 'quesiton 3',
    answer: 'answer 3',
    id: 3,
    __v: 0
  }
]

And this is the new array I send to the backend

[
  {
    _id: '5ed276129b268308302cb1ff',
    question: 'quesiton 3',
    answer: 'answer 3',
    order: 3,
    __v: 0
  },
  {
    _id: '5ed273049b268308302cb1fb',
    question: 'question 1',
    answer: 'answer 1',
    order: 1,
    __v: 0
  },
  {
    _id: '5ed273439b268308302cb1fd',
    question: 'question 2',
    answer: 'answer 2',
    order: 2,
    __v: 0
  }
]

Solution

  • If you updating the documents, use the index values from the array to update the order id.

    const promises = order.map( async (o, index) => {
    
      let orderkey = index + 1;
      const promise = Faq.updateOne({ _id: o._id }, { $set: { order: orderkey } });
    
      return promise;
    
    });
    
    const results = await Promise.all(promises);
    

    This way the order key will be updated based on the order of the array you are sending .

    But think about actually updating the order key already in the frontend, before sending it to the backend. This way the order of the array wouldn't matter.