Home > Blockchain >  Having problems using delete method in MERN stack
Having problems using delete method in MERN stack

Time:11-19

I am practicing using the MERN stack for the first time. I was using this tutorial loosely as a guide but I made some of my own tweaks to make the app function as a social media site. My backend code works fine, as I've tested it using Postman and it gives me the desired result. But when I put the button on my React project and call the onClick method, nothing happens with the request. Every other method works as desired in my project besides this one.

Feed.js

import React, {Component} from "react"
import Card from 'react-bootstrap/Card';
import Button from 'react-bootstrap/Button';
import axios from 'axios';
import {Link} from "react-router-dom"
// import {Link} from "react-router-dom"

const renderCard = props => {
   return (
    <>
      <Card style={{ width: '30rem', marginLeft:'auto', marginRight:'auto'}}>
      <Card.Body>
        <Card.Title>{props.username} says: </Card.Title>
        <Card.Text> {props.text}</Card.Text>
       <Link to = {"/edit/"  props._id}>
        <Button style={{marginRight: '10px'}} variant="secondary">Edit {props.username}'s Profile</Button>
       </Link>
        <Button variant="danger" onClick = {props.deletePost(props.id)}>Delete Post</Button>{' '}
      </Card.Body>
    </Card>
    <br/>
    </>
     )
}
export default class Feed extends Component {

  constructor(props) {
    super(props);

    this.deletePost = this.deletePost.bind(this)

    this.state = {
      postedBy: '',
      username: '',
      text: '',
      id: '',
      posts: []
    };
  }

  componentDidMount() {
    axios.get('http://localhost:9998/posts/')
      .then(response => {
        this.setState({ posts: response.data })
      })
      .catch((error) => {
        console.log(error);
      })
  }


  deletePost(id) {
    axios.delete('http://localhost:9998/posts/' id)
      .then(response => { console.log(response.data)});

    this.setState({
      posts: this.state.posts.filter(element => element._id !== id)
    })
  }

   render() {
    return (
    <div>
      <h1 style = {{marginLeft:'auto', marginRight:'auto'}}>Home</h1>
      <hr/>
    <div>{this.state.posts.map(renderCard)} </div> 
    </div>
    )
   }
}

Posts.js (route)

const router = require("express").Router();
let Post = require("../models/posts.model");

// Get all posts

router.route("/").get((req, res) => {
    Post.find()
      .then((posts) => res.json(posts))
      .catch((err) => res.status(400).json("Error "   err));
  });

// Add new posts

router.route("/add").post((req, res) => {
    const text = req.body.text; 
    const photo = req.body.photo;
    const likes = req.body.likes;
    const comments = req.body.comments;
    const created = req.body.created;
    const username = req.body.username;

    const newPost = new Post ({
        text,
        photo,
        likes,
        comments,
        created,
        username
    });

    newPost.save()
      .then(() => res.json("Post added!"))
      .catch((err) => res.status(400).json("Error: "   err))

});


router.route("/:id").delete((req, res) => {
    Post.findByIdAndDelete(req.params.id)
      .then(() => res.json("Post deleted!"))
      .catch((err) => res.status(400).json("Error: "   err))
});



  module.exports = router;

I believe the issue lies within this line and I'm using props incorrectly. I expect this code to delete the post from the MongoDB database and delete the card/post from the UI.

        <Button variant="danger" onClick = {props.deletePost(props.id)}>Delete Post</Button>{' '}

CodePudding user response:

You are right about that line. What you are doing is calling props.deletePost(props.id) on render instead of onClick

Try wrapping it with anonymous function like onClick={() => props.deletePost(props.id)}

Edit:

You are setting renderCard here and passing in individual post as props variable

<div>{this.state.posts.map(renderCard)} </div>

One potential solution would be to pass deletePost to renderCard function like

.map((post) => renderCard({ deletePost: this.deletePost, ...post}))

and keep renderCard the same

  • Related