le0nicolas
le0nicolas

Reputation: 83

How to delete data from DB using React, and hitting a rest API that i created using php and mysql?

The api works fine because I already tested it in postman, and I've managed to create the front end and show all the data stored in my api, now I want to press a button and delete the particular item I want. When I press the delete button, an alert pops up with the id of the current item, so I know passing the id isn't an issue. The problem is when I use the fetch function.

Here's the delete function from my api:

public function delete(){
        //crear query
        $query = 'DELETE FROM ' . $this->table . ' WHERE ID = :ID';
        //prepare statement
        $stmt = $this->conn->prepare($query);
        //clean data
        $this->ID = htmlspecialchars(strip_tags($this->ID));
        //bind data
        $stmt->bindParam(':ID', $this->ID);
        //execute query
        if($stmt->execute()){
            return true;
        }
        //print error if something goes wrong %s es un placeholder
        printf("Error: %s. \n", $stmt->error);          
        return false;
    }

Here's the react code (check the function handleBorrar):

import React from 'react';

class Pelicula extends React.Component{

    constructor(props){
        super(props);
        this.state={
          loading:true,
          pelicula:null,
        };
    }

    async handleBorrar(id) {
        alert(`hello, ${id}`);
        const responseDel = await fetch(`http://localhost/APIpeliculas/api/pelicula/read.php/${id}`, {
          method: "DELETE",
        });
        return responseDel.json();
    }

    async componentDidMount(){
        const url = "http://localhost/APIpeliculas/api/pelicula/read.php";
        const response = await fetch(url);
        const result = await response.json();
        this.setState({pelicula:result.data, loading: false});
        document.body.style.backgroundColor = "burlywood";
    }
    
    render(){

        if (this.state.loading){
            return <div> loading... </div>
        }

        if(!this.state.pelicula){
            return <div> Sin peliculas... </div>
        }
        return(
            <div className="container">
                <div className="row">
                    {
                        this.state.pelicula.map((peli, index)=>{
                            return(                             
                                <div key = {index} className="col-sm-12 col-md-6 col-lg-4 mt-3 d-flex justify-content-center col-style">
                                    <div className="card card-style">
                                        <div className="card-body">
                                            <h5 className="card-title">{peli.Nombre}</h5>
                                            <h6 className="card-subtitle mb-2 text-muted">{peli.Categoria}</h6>
                                            <p className="card-title"> {peli.Director} </p>
                                            <button type="button" className="btn btn-labeled btn-danger"  onClick={() => this.handleBorrar(peli.ID)}> Borrar </button>
                                            <button type="button" className="btn btn-labeled btn-warning"> Editar </button>
                                        </div>
                                    </div>
                                </div>
                            )
                        })
                    }
                </div>
            </div>
        )
    }
}

export default Pelicula;

I got some ideas for the fetch DELETE method by reading another questions from here, but I'm not sure how it will work. What is the json that will return? Also, will react render everything again and call the api to update everything or will I have to reload the page to see the results?

Also, I'm not sure if I'm using the right url, since when I made the api and tested it in postman, to delete and item I have to use the url: http://localhost/APIpeliculas/api/pelicula/delete.php and then pass the ID on the body as a JSON object. So I'm not sure how will it work, since the route for my api won't take a delete.php/ID route.

Upvotes: 1

Views: 1528

Answers (1)

Rodrigo Amaral
Rodrigo Amaral

Reputation: 1382

If you're using a RESTful API, there's no mandatory response when you delete a resource successfully. You can return status 204 when the resource is deleted and some of the 400 statuses when something goes bad. See this question for suggestions. You don't even need to get the body of the request, as you are not using it anyway.

If an item has been deleted from DB, it makes sense to also remove it from your view. You can do so by refreshing the page (not a good idea), by reloading the list or by filtering the array, as in:

  removeById = (id) => {
    this.setState((state) => ({
      pelicula: state.pelicula.filter((item) => item.id !== id)
    }));
  };

  async handleBorrar(id) {
    alert(`hello, ${id}`);
    try {
      const responseDel = await fetch(
        `http://localhost/APIpeliculas/api/pelicula/read.php/${id}`,
        {
          method: "DELETE"
        }
      );

      if (!responseDel.ok) throw new Error("API request not ok");

      if (responseDel.status >= 400 && responseDel.status < 600) {
        throw new Error("Bad response from server");
      }

      this.removeById(id);
    } catch (error) {
      // do something with the error, maybe warn the user
    }
  }

Upvotes: 1

Related Questions