Home > Back-end >  likes counter with AJAX (and Symfony)
likes counter with AJAX (and Symfony)

Time:02-01

I've got likes system on my website (one like button that becomes empty or filled when clicking) and it works perfectly fine in terms of server side. My issue is the likes counter. I want it to refresh likes count without page reload and cannot really figure out how. I'm kinda newbie with AJAX and that's why I'm here.

Here is my code:

CommentLikeController.php

 /**
     * @Route("/comments/like-unlike", name="app_comment_like_unlike")
     */
    public function like(Request $request, EntityManagerInterface $entityManager): Response
    {

        if ($request->getMethod() === 'POST'){

            //retrieve commentId from AJAX request
            $commentId = $request->request->get('entityId');

            //check if comment exists
            $comment = $entityManager->getRepository(Comment::class)->findOneBy(['id'=> $commentId]);

            // return void if not
            if (!$comment){
                return new JsonResponse();
            }

            // retrieve csrf Token from AJAX request
            $submittedToken = $request->request->get('csrfToken');

            // check if it's valid
            if ($this->isCsrfTokenValid('comment' . $comment->getId(), $submittedToken)){

                $user = $this->getUser();

                $commentAlreadyLiked = $entityManager->getRepository(CommentLike::class)
                    ->findOneBy(['user' => $user, 'comment' => $comment]);

                // if user unlikes the comment, remove it from DB
                if($commentAlreadyLiked){
                    $entityManager->remove($commentAlreadyLiked);
                    $entityManager->flush();
                    return new JsonResponse();
                    // if user likes the comment, add record to DB
                } else{
                    $like = new CommentLike();
                    $like->setUser($user);
                    $like->setComment($comment);
                    $entityManager->persist($like);
                    $entityManager->flush();
                }

            }

        }
        return new JsonResponse();
    }

index.html.twig

<div >
    <a href="{{ path('app_comment_like_unlike') }}"
       id="comment-like"
       data-entity-id="{{ comment.id }}"
       data-csrf-token="{{ csrf_token('comment' ~ comment.id) }}"
       data-liked="{{ comment.commentLikes.isEmpty == true ? '0' : '1' }}"
       data-likes-counter="{{ comment.commentLikes.count }}"
       >
        <i >
            {{ comment.commentLikes.isEmpty == true ? '♡' : '♥' }}
        </i>
    </a>
    <span >{{ comment.commentLikes.count }}</span>
</div>

{% block javascripts %}
    {{ parent() }}
    <script src="{{ asset('js/comments_like_unlike.js') }}"></script>
{% endblock %}

comments_like_unlike.js

$(document).on('click', '#comment-like', function (e) {
    e.preventDefault();

    var url = $(this).attr('href');
    var entityId = $(this).attr('data-entity-id');
    var csrfToken = $(this).attr('data-csrf-token');
    var isLiked = $(this).attr('data-liked');
    var likesCounter = $(this).attr('data-likes-counter');

    if (isLiked === '0') {
        $(this).attr('data-liked', 1);
        $('.♡').addClass('liked').text('♥')
        likesCounter  ;
    } else {
        $(this).attr('data-liked', 0);
        $('.♡').removeClass('liked').text('♡')
        likesCounter--;
    }
    $.ajax({
        type: 'POST',
        dataType: 'json',
        data: {'entityId': entityId, 'csrfToken': csrfToken, 'likesCounter': likesCounter},
        url: url,
        success: function () {
            console.log("success");
        },
        error: function () {
        }
    });
});

Your help and any explanations are greatly appreciated!

I tried checking and using others' examples of this part on the web but it didn't work out

CodePudding user response:

Here you can do return number likes from server:

else{
   $like = new CommentLike();
   $like->setUser($user);
   $like->setComment($comment);
   $entityManager->persist($like);
   $entityManager->flush();

   return new JsonResponse(
   'countLikes' => $like->getComment()->getCommentLikes()->count()
   )

}

In twig add id to this span

 <span  id="count-likes-{{ comment.id }}">{{ comment.commentLikes.count }}</span>

Ajax

    success: function (response) {
       // countLikes is returned in json response from the server
       $('#count-likes-'   entityId).text(response['countLikes']);
    },

or you can do it directly in the success function without any change in the controller and without return the numbers of likes from the server

      success: function (response) {
      
       $('#count-likes-'   entityId).text(parseInt(likesCounter)   1);
    },
  • Related