How to Delete API Data in React and Update State
Now that we have a handler built, that is listening for any user to click on Delete, we now have the ability to call the outside API, pass in the delete verb and then have it remove that record from the database.
Guide Tasks
  • Read Tutorial
  • Watch Guide Video
Video locked
This video is viewable to users with a Bottega Bootcamp license

Now I will say make sure that you're only performing this task with data that you want to delete because just like any other application, once you remove this record, it is no longer going to be there, neither are any of the images, any of the metadata, so if you're doing this with your real portfolio items, make sure that you create some sample ones that you are fine deleting.

So with all that being said, let's open up the code, let's switch to Visual Studio Code and inside of our handleDeleteClick, we are going to call axios, it's like we've been doing throughout this course but this time, instead of calling it and asking for some data, we're going to say that we want to delete some data.

Now if you scroll up all the way up at the top, make sure that you have axios already imported and you should already have it if you have the rest of the application working. And now I'm gonna get rid of our console.log statement here and I'm gonna start building out the calls.

So I'm gonna say axios. and we've used this function before but it's the delete function that is available. So we are not gonna be calling a get request or a post request. In this case, we're calling delete, and then we need to pass in the API that we wanna call.

Now I'm gonna be using the backticks here, these are not apostrophes, so that we can use string interpolation and to pass in some dynamic data 'cause remember, we need to be able to tell the API which record to delete and the only way we can do that is with this portfolio item record.

So we're going to be passing that directly into the API call. So I'm gonna start off by saying https: //api.devcamp.space and then from there portfolio just like we've done so far and then /portfolio_items/ and this is where we want to pass in the actual record so this I'm going to use our string interpolation.

So I'm going to say dollar sign curly brackets and then inside of here, pass in portfolioItem which we're getting from the deleteClick handler and then we want the ID for that. So this is going to give us something that looks a little bit like this so if I were to get rid of everything here, it would give us a URL that if our portfolioItem had an ID of say 10 it would look like this and that's what the API is expecting and that's pretty standard for most APIs.

axios.delete(`https://api.devcamp.space/portfolio/portfolio_items/${portfolioItem.id}`,
    { withCredentials: true }
  )

So you pass in the ID, what the API is gonna do is it's going to take in all of the data and it's gonna run its own database query, it's gonna find a portfolioItem with whatever the ID is and then it's going to then delete that assuming that you have the ability to do so.

So we have this delete here and at the very end up here before we have the parens, make sure you close off your backtick and then before you close off the actual delete function, give it a comma and then in curly brackets say withCredentials: true just like that, just like we've done before.

And this is how the API is gonna know if you're allowed to delete a portfolioItem 'cause remember, we need to have some security here so the API, what it does is it takes in the ID, then it checks that against you as a user. So it's going to grab the withCredentials: true, it' gonna look you up to see what user account that you have access to, it's going to check and see if these records are inside of your account, if they belong to you and if all of those things line up, then it's gonna delete the record. If not, it's gonna give you an error and it's gonna say that you're not authorized to delete that item.

But in this case, I'm logged in so we shouldn't have an issue here. So I'm gonna say withCredentials: true and then you can close off your parens. If I hit save, the prettier extension is going to make this look a lot nicer so we have axios.delete, the URL, make sure you have a comma at the very end because the URL is the first argument in the list in that delete function, the second argument is this object where we say withCredentials: true.

portfolio-manager.js

handleDeleteClick(portfolioItem) {
  axios.delete(
    `https://api.devcamp.space/portfolio/portfolio_items/${portfolioItem.id}`,
    { withCredentials: true }
  )
}

Now that we have that, now I can call then 'cause remember that delete in axios is passing back a promise so we say when this response comes back, then I wanna do something with it, so I wanna take that response and pass it an arrow function and for right now let's just print it out, I'll say console.log response from delete and then also call response just to see what's there.

And then if there are any errors, I want to catch those so I'll say error and then console.log and this one I will take the name of the function, put it in a string, and say handleDeleteClick error and then make sure I print out the error. Okay, so that's also been nice and prettified.

handleDeleteClick(portfolioItem) {
  axios
    .delete(
      `https://api.devcamp.space/portfolio/portfolio_items/${portfolioItem.id}`,
      { withCredentials: true }
    )
    .then(response => {
      console.log("response from delete", response);
    })
    .catch(error => {
      console.log("handleDeleteClick error", error);
    });
}

So this is gonna look a little bit better. So let's test this out, let's see if this is working. Now this is not gonna remove the record from state yet, that's what we have to do after this but let's test it out to see if it's working up to this point. So make sure you open up the console here, and I'm also gonna just give it a refresh just to make sure we don't have anything in our cache and so we have final test here if I click Delete, we get a response from delete.

So it looks like everything worked. Now we don't get any data back which is fine, we're getting an empty response back but I didn't get any errors so this means it most likely worked so let's hit refresh and this final test should no longer be there. And let's see, there we go, it's no longer there, so that was deleted.

So everything that we're doing so far is working. The last thing that we need to do is we need to when this response comes back, we need to iterate over our state items, over our portfolioItems and remove that record from state. So let's do that now.

I'm gonna get rid of this console.log statement here and then say this.setState and then inside of setState, I'm going to take our portfolioItems and then inside of here, this is gonna be where it's a little bit trickier, so make sure you pay attention to what I'm typing and then also follow along afterwards because what we need to do is inside of what we're setting, we're actually going to iterate and build a new collection on the fly and we're gonna use the filter function to do that.

So the way I can do that is by saying that this.state so now I'm actually calling state and our portfolioItems so I'm calling the current value of the items and then I'm gonna call filter and then filter kinda like a map or any of the other functions, it's going to allow us to grab, it's gonna allow us to get access to each one of those data elements.

So the first time it goes through, it's gonna give us the first portfolioItem, that whole object, and then we can do whatever we wanna do with it. But now where map allows us to build a new collection, what filters used typically for is to iterate through a collection and only keep certain items and that's exactly what we're wanting to do here. We're wanting to keep all of the items except for the record that has the same ID of what we just deleted.

So here, I can say filter and let's just call it item because I don't wanna get it confused with the portfolioItem that we have up here 'cause we're gonna have to call that. So because this is a function and it's just a variable, we can call it anything we want.

So I'm gonna say item and so this is gonna iterate over each time, make sure you call return and say return item.id and then with a bang, so exclamation mark equals equals portfolioItems so this is our record coming in from the argument, this is what we're getting of what got clicked. So I'm gonna say portfolioItem.id and then at the very end, this is outside of setState, we're gonna just return response.data which we know it's empty but it's just so the function actually returns something.

And so what is going to happen here is once a response comes back, then we're going to setState. We're going to say we want to clean up our portfolioItems here and so, what we wanna do is call this.state.portfolioItems so we wanna grab the current collection and we want to filter it.

We wanna say that as you iterate through if you find a record and the item.id is not equal to the ID right here that we want to delete, then I want you to return that meaning that I want you to keep those records but I want you to get rid of the one record that has that ID. Now keep in mind, this is all very surfacy, this is only so that we can auto-update our application state, this doesn't have anything to do with the server.

The server and the record got deleted up here so everything got taken care of here in the delete process. This is our real data. What we're trying to do is we're simply wanting to update our local application state so that it matches with reality.

If I typed everything correctly here, then this should work. So come back here, let's hit refresh and so we have this testing with refs. If I hit Delete here, then it deleted it, so that worked perfectly and if you hit refresh again, you can see that is no longer there.

So this is working perfectly and now we can click Delete and it will automatically delete the record and also update our application state.

Resources