Kahalon
Kahalon

Reputation: 119

Http PUT deletes data that hasn't been changed

I am trying to edit a JSON data base of shifts. I am writing in Javascript using react. This is my understanding of the PUT syntax:

const editShift = async (changed, id) => {

  const res = await fetch(`http://localhost:5000/shifts/${id}`, {
    method: 'PUT', 
    headers: {
    'Content-type': 'application/json' 
    },
    body: JSON.stringify(changed)
 })
 const data = await res.json()
 setShifts([...shifts, data])
}

data.json:

{
  "shifts": [
    {
      "title": "test",
      "startDate": "2018-06-25T07:30:00.000Z",
      "endDate": "2018-06-25T08:00:00.000Z",
      "allDay": false,
      "id": 1
    },
    {
      "title": "test2",
      "startDate": "2018-06-28T07:30:00.000Z",
      "endDate": "2018-06-28T08:00:00.000Z",
      "allDay": false,
      "id": 2
    }
  ]
}

The result is that the new shift will hold only the fields that have been changed and delete the rest. Any ideas why?

Upvotes: 0

Views: 323

Answers (5)

Evert
Evert

Reputation: 99717

PUT requests replace all the data at the target URI. They don't automatically merge changes.

It's not clear if you are the author of this API or just a consumer, but if you are consuming the API you should either look for a different API that lets you only send edits (HTTP method might be POST or PATCH), or you need to send the entire list of shifts.

Alternatively it might also be possible that there's a specific endpoint for each shift, so you can send exactly 1 PUT request to a shift endpoint just to edit that specific endpoint.

Upvotes: 0

theOneWhoKnocks
theOneWhoKnocks

Reputation: 658

For a question like this, it'd be helpful if you posted before and after examples of data

  • database empty
  • request #1, payload equals X
  • request #2, payload equals Y

Also, knowing what your Server handler is doing would help determine what's going on. I have a feeling what's happening is something like this

// API handler
(req) => {
  const dbData = getDBData();
  dbData.shifts = req.shifts; // overwrite old with new
}

When what you need is something like

(req) => {
  const dbData = getDBData();
  req.shifts.forEach((newShiftData) => {
    const shiftId = newShiftData.id;

    if (dbData[shiftId]) {
      dbData[shiftId] = { ...dbData[shiftId], ...newShiftData }; // merge old with new
    }
  });

  // - check if data changed
  // - update DB
}

Upvotes: 0

Kahalon
Kahalon

Reputation: 119

I had to send the whole updated shift into the changed field, with the fields that were not changed. I don't know why but it works so okay.

Upvotes: 0

Gijs Beijer
Gijs Beijer

Reputation: 624

The PUT request should work like that.

A PUT request should PUT the data into place of the old record. You would want to use a PATCH request for only PATCHing data upon the old record.

That set aside, it depends on your /shifts endpoint on how this is actually handled.

Upvotes: 2

Sowam
Sowam

Reputation: 1756

To get previous shifts you should use a callback inside setShifts like:

setShifts(prevShifts => ([...prevShifts, data]))

Upvotes: 1

Related Questions