I am trying to update the like/upvote button. For that I have created a menthod[Method named: likepost()] in my Controller named Posts. Here is the code for my method.
public function likepost()
{
if (IsloggedIn()) {
// Check if the request is a POST request
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
$post_id = $_POST['post_id'];
$user_id = $_SESSION['user_id']; // Assuming the user is logged in and we are storing the user ID in session
// Check if the user already liked this post
if ($this->postModel->hasUserLikedPost($post_id, $user_id)) {
// User has already liked the post, so we need to remove the like
if ($this->postModel->removeLike($post_id, $user_id)) {
// Decrease the like count in the posts table
$this->postModel->decrementLikeCount($post_id);
echo json_encode(['status' => 'unliked', 'likes_count' => $this->postModel->getLikesCount($post_id)]);
}
} else {
// User has not liked the post, so we add the like
if ($this->postModel->addLike($post_id, $user_id)) {
// Increase the like count in the posts table
$this->postModel->incrementLikeCount($post_id);
echo json_encode(['status' => 'liked', 'likes_count' => $this->postModel->getLikesCount($post_id)]);
}
}
} else {
echo json_encode(['status' => 'error', 'message' => 'Invalid request']);
}
} else {
echo json_encode(['status' => 'error', 'message' => 'User not logged in']);
}
}
Following is the code for my Model:
public function hasUserLikedPost($user_id, $post_id) {
echo $this->db->query('SELECT * FROM post_likes WHERE user_id = :user_id AND post_id = :post_id');
$this->db->bind(':user_id', $user_id);
$this->db->bind(':post_id', $post_id);
$row = $this->db->single();
return $row ? true : false;
}
public function addLike($post_id, $user_id) {
$this->db->query('INSERT INTO post_likes (post_id, user_id) VALUES (:post_id, :user_id)');
$this->db->bind(':post_id', $post_id);
$this->db->bind(':user_id', $user_id);
return $this->db->execute();
}
public function removeLike($post_id, $user_id) {
$this->db->query('DELETE FROM post_likes WHERE post_id = :post_id AND user_id = :user_id');
$this->db->bind(':post_id', $post_id);
$this->db->bind(':user_id', $user_id);
return $this->db->execute();
}
public function incrementLikeCount($post_id) {
$this->db->query('UPDATE posts SET likes_count = likes_count + 1 WHERE id = :post_id');
$this->db->bind(':post_id', $post_id);
return $this->db->execute();
}
public function decrementLikeCount($post_id) {
$this->db->query('UPDATE posts SET likes_count = likes_count - 1 WHERE id = :post_id');
$this->db->bind(':post_id', $post_id);
return $this->db->execute();
}
public function getLikesCount($post_id) {
$this->db->query('SELECT likes_count FROM posts WHERE id = :post_id');
$this->db->bind(':post_id', $post_id);
return $this->db->single()->likes_count;
}
Here is my view code:
<button class="btn btn-success" id="upvote" data-post-id='<?php echo $data['post']->id; ?>'>
<i class="fa fa-thumbs-up"></i> Upvote <span id="display"><?php echo $data['post']->likes_count; ?></span>
</button>
Following is my AJAX query written in my main.js
document.addEventListener("DOMContentLoaded", function () {
let btn = document.getElementById("upvote");
if (!btn) {
console.error('Element with ID "upvote" not found');
return;
}
let disp = document.getElementById("display");
let post_id = btn.getAttribute("data-post-id");
btn.onclick = function () {
// Create an AJAX request to send the post_id to PHP
let xhr = new XMLHttpRequest();
xhr.open("POST", "<?php echo URLROOT;?>/posts/likepost", true);
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xhr.onreadystatechange = function () {
if (xhr.readyState === 4 && xhr.status === 200) {
// Handle the response from PHP
let response = JSON.parse(xhr.responseText);
if (response.status === 'liked') {
disp.innerHTML = response.likes_count; // Update the like count
} else if (response.status === 'unliked') {
disp.innerHTML = response.likes_count; // Update the like count
}
}
};
// Send the post_id as part of the request
xhr.send("post_id=" + post_id);
}
});
Whenever i am trying to run this i am getting following error in my console:
As per this error it is showing error in my another method which is running fine, i am pasting that here for reference as well:
public function show($id)
{
$post = $this->postModel->getPostById($id);
$user = $this->userModel->getUserById($post->userid);
$data = [
'post' => $post,
'user' => $user,
];
$this->view('posts/show',$data);
}
2
Answers
I think @James is right. Basically : in the
show($id)
, the value of$post
is not the object you are expecting from the DB, it isfalse
.And when you try to read the property
userid
from false instead of an object, it gives you this error.There are some things to check :
let post_id = btn.getAttribute("data-post-id");
gets you exactly thepost_id
you expect and is correctly sentpost_id
sent from xhr is the good one when it arrives toshow($id)
show($id)
that$id
is a valid value (not "" or 0 or false for example)$this->postModel->getPostById()
does correctly its job$id
exists in your database if there is still the problem (if it doesn’t, you have a problem somewhere else)I think you’ll be able to solve your problem with that.
The first issue here is your returning HTML not JSON data, so the error is related to your code trying to parse the HMTL into a JSON array, which is not right.
Either change your javascript to reflect that you are responding with HTML or if that is a mistake, make sure your response is correct JSON.
I can also see from your inspect that the page you are testing has a PHP error, this might be related to the JSON issue if the same error is being spat out just before the JSON data, you can check this by looking at the XHR requests tab and you should be able to see your ajax request and response data.