Update the likes array in a post in the frontend

Viewed 569

I have a PUT route in the backend for liking posts, it adds the users id to the likes array in the post. This works fine when tested on Postman (by providing the post in the body) and the likes array is updated. However, when the icon is clicked in the frontend, I want the likes array to update but I'm not sure how to update the state for the post. result is showing the response in the frontend with a 200 status code but that's as far as I'm getting.

How can I update the likes array in the frontend?

Post.js

const Post = (props) => {
  const [post, setPost] = useState({});
  const [error, setError] = useState(false);
  const id = props.match.params.id;

  const loadSinglePost = (id) => {
    read(id).then((data) => {
      if (error) {
        console.log(data.error);
        setError(data.error);
      } else {
        setPost(data);
        console.log(data);
      }
    });
  };

  useEffect(() => {
    loadSinglePost(id);
  }, [props]);

  const like = (id) => {
    const {user: { _id }, token} = isAuthenticated();
    fetch(`${API}/like/${_id}`, {
      method: "PUT",
      headers: {
        "Content-Type": "application/json",
        Authorization: `Bearer ${token}`,
      },
      body: JSON.stringify({
        id: id,
      }),
    })
      .then(result => { console.log(result)})
      .catch((err) => {
        console.log(err);
      });
  };
  return (
    <div>
      <Navbar />
      <div>
        <h3>{post && post.title}</h3>
          <p>
            {post && post.author ? post.author.name : ""}
          </p>
        <p>{post && post.body}</p>
        <h5>{post && post.likes && post.likes.length} likes</h5>
        <img
          onClick={() => {
            like(id);
          }}
          alt="..."
        />
      </div>
    </div>
  );
};

export default Post;

controllers/post.js

exports.like = (req, res) => {
  Post.findByIdAndUpdate(req.body._id, {
    $push: {likes: req.profile._id}
  }, {new: true}).exec((err, result) => {
    if (err) {
      return res.status(422).json({error: err})
    } else {
      return res.json(result)
    }
  })
}

exports.readById = (req, res) => {
  const id = req.params.id
  Post.findById(id)
    .then(post => res.json(post))
    .catch(err => res.status(400).json('Error: ' + err));
}
1 Answers

You can update likes in post in then callback like this:

const like = (id) => {
    const {user: { _id }, token} = isAuthenticated();
    fetch(`${API}/like/${_id}`, {
        method: "PUT",
        headers: {
            "Content-Type": "application/json",
            Authorization: `Bearer ${token}`,
        },
        body: JSON.stringify({
            id: id,
        }),
    })
    .then(result => {
         // here update post likes 
         let updatedPost = {...post}; //to make copy of post 
         updatedPost.likes = [...updatedPost.likes, id]; //add new id to updatedPost' likes array
         setPost(updatedPost); //update post
         console.log(result)
    })
    .catch((err) => {
        console.log(err);
    });
}; 

Also from front-end you're sending id key in body:

body: JSON.stringify({
          id: id,  // here
      })

And at back end you're expecting _id

Post.findByIdAndUpdate(req.body._id, { // here
    $push: {likes: req.profile._id}
}
Related