I have this ajax function of liking and disliking a comment but with this function, I can like and dislike at the same time. for example When I like the comment it is liking it and if after that I dislike it does that too without removing my like.
Here is the code for like (upvote) and dislike (downvote)
up votes
$(".tup").click(function (e) {
e.preventDefault();
var reviewId = $(this).data('id');
$.ajax({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
},
url: document.location.origin + '/review/' + reviewId + '/upvote',
type: 'POST',
data: {
review_id: reviewId
},
dataType: 'json'
})
.done(function (data) {
if (data == true) {
$('.tup[data-id=' + reviewId + '] .vn').text(function (i, oldVal)
{
return parseInt(oldVal, 10) + 1;
});
} else {
snackybar.timer("Already Voted", 3000);
}
})
.fail(function (jqXHR, textStatus) {
console.log("Request failed: " + textStatus);
});
});
// down votes
$(".tdown").click(function (e) {
e.preventDefault();
var reviewId = $(this).data('id');
$.ajax({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
},
url: document.location.origin + '/review/' + reviewId + '/downvote',
type: 'POST',
data: {
review_id: reviewId
},
dataType: 'json'
})
.done(function (data) {
if (data == true) {
$('.tdown[data-id=' + reviewId + '] .vn').text(function (i, oldVal) {
return parseInt(oldVal, 10) + 1;
});
} else {
snackybar.timer("Already Voted", 3000);
}
})
.fail(function (jqXHR, textStatus) {
console.log("Request failed: " + textStatus);
});
});
And this is the controller's code
public function upvote($id) {
if(!UpDownVote::where('review_id',$id)->where('upvote',1)->first()) {
Review::findOrFail($id)->increment('upvote');
UpDownVote::create([
'user_id' => Auth::user()->id,
'review_id' => $id,
'upvote' => 1
]);
return 'true';
} else {
return 'false';
}
}
public function downvote($id) {
if(!UpDownVote::where('review_id',$id)->where('downvote',1)->first()) {
Review::findOrFail($id)->increment('downvote');
UpDownVote::create([
'user_id' => Auth::user()->id,
'review_id' => $id,
'downvote' => 1
]);
return 'true';
} else {
return 'false';
}
}
The issue is that your Ajax calls are asynchronous; thus, when clicking on tup
button and then the tdown
one, perhas the treatment have not been done already when you click on the second button.
You can disabled the possibility of clicking when you are waiting for the server response.
var isClicking = false;
$(".tup").click(function (e) {
if(isClicking){
return;
}
isClicking = true;
e.preventDefault();
var reviewId = $(this).data('id');
$.ajax({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
},
url: document.location.origin + '/review/' + reviewId + '/upvote',
type: 'POST',
data: {
review_id: reviewId
},
dataType: 'json'
})
.done(function (data) {
if (data == true) {
$('.tup[data-id=' + reviewId + '] .vn').text(function (i, oldVal)
{
return parseInt(oldVal, 10) + 1;
});
} else {
snackybar.timer("Already Voted", 3000);
}
})
.fail(function (jqXHR, textStatus) {
console.log("Request failed: " + textStatus);
}).always(function(){
isClicking=false;
});
});
// down votes
$(".tdown").click(function (e) {
e.preventDefault();
if(isClicking){
return;
}
isClicking = true;
var reviewId = $(this).data('id');
$.ajax({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
},
url: document.location.origin + '/review/' + reviewId + '/downvote',
type: 'POST',
data: {
review_id: reviewId
},
dataType: 'json'
})
.done(function (data) {
if (data == true) {
$('.tdown[data-id=' + reviewId + '] .vn').text(function (i, oldVal) {
return parseInt(oldVal, 10) + 1;
});
} else {
snackybar.timer("Already Voted", 3000);
}
})
.fail(function (jqXHR, textStatus) {
console.log("Request failed: " + textStatus);
}).always(function(){
isClicking=false;
});
});