2
\$\begingroup\$

How can I improve this code ? It was quite hard to implement AJAX comment system in Symfony 3, and result is a bit of mess:

Controller:

<?php
declare(strict_types = 1);
namespace AppBundle\Controller;

use AppBundle\Entity\Article;
use AppBundle\Entity\ArticleCategory;
use AppBundle\Entity\Comment;
use AppBundle\Entity\User;
use AppBundle\Entity\UserLikedArticles;
use AppBundle\Form\CommentFormType;
use AppBundle\Repository\ArticleRepository;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;

class ArticleController extends Controller
{
    /**
     * @Route("/articles/{category}", name="articles")
     */
    public function getArticles(string $category) : object
    {
        $em = $this->getDoctrine()->getManager();
        $categoryId = $em->getRepository('AppBundle:ArticleCategory')->getCategoryIdByCode($category);
        $articles = $em->getRepository('AppBundle:Article')->findAllByCategory((int)$categoryId);
        return $this->render('articles/articles.html.twig', [
            'articles' => $articles
        ]);
    }

    /**
     * @Route("/articles/{category}/{id}", name="article")
     */
    public function getArticle($category, $id)
    {
        $isFavourite = false;
        $isLikedArticle = false;
        $isUnlikedArticle = false;

        $articleRepo = $this->getDoctrine()->getRepository(Article::class);
        $article = $articleRepo->find($id);

        $categoryRepo = $this->getDoctrine()->getRepository(ArticleCategory::class);
        $categories = $categoryRepo->findAll();

        $categoryId = $categoryRepo->getCategoryIdByCode($category);
        $lastArticles = $articleRepo->getLimitArticlesByCategory((int)$categoryId, 3);

        $nextArticle = $articleRepo->getNextArticle((int)$categoryId, $id);
        $previousArticle = $articleRepo->getPreviousArticle((int)$categoryId, $id);

        if ($this->isGranted('ROLE_USER')) {
            $userRepo = $this->getDoctrine()->getRepository(User::class);
            $user = $this->getUser();
            $user = $userRepo->find($user->getId());
            $userFavouriteArticles = $user->getFavouriteArticles();

            $userLikedArticle = $this->getDoctrine()->getRepository('AppBundle:UserLikedArticles')
                ->findOneBy(array(
                    'userId' => $user,
                    'articleId' => $article,
                ));

            if ($userLikedArticle) {
                $userLikedArticle->getAppraisal() == 'like' ? $isLikedArticle = true : $isUnlikedArticle = true;
            }

            foreach ($userFavouriteArticles as $userFavouriteArticle) {
                if ($userFavouriteArticle->getId() == $id) {
                    $isFavourite = true;
                }
            }
        }

        if (is_null($nextArticle)) {
            $nextArticle = $articleRepo->getRandomArticle((int)$categoryId, $id);
        }

        if (is_null($previousArticle)) {
            $previousArticle = $articleRepo->getRandomArticle((int)$categoryId, $id);
        }

        $commentForm = $this->createForm(CommentFormType::class);

        return $this->render('articles/article.html.twig', [
            'article' => $article,
            'categories' => $categories,
            'lastArticles' => $lastArticles,
            'nextArticle' => $nextArticle,
            'previousArticle' => $previousArticle,
            'commentForm' => $commentForm->createView(),
            'isFavourite' => $isFavourite,
            'isLikedArticle' => $isLikedArticle,
            'isUnlikedArticle' => $isUnlikedArticle
        ]);
    }

    /**
     * @Route("/articles/{category}/{id}/addcomment/{replyToId}", defaults={"replyToId"=0}, name="addcomment")
     */
    public function addComment(Request $request, $category, $id, $replyToId)
    {
        $status = 'error';
        $message = '';

        if (!$this->isGranted('ROLE_USER')) {
            echo 'ne e lognat'; exit;
            $message = 'Трябва да се логнете, за да добавите нов коментар!';
        } else {
            $form = $this->createForm(CommentFormType::class);

            $form->handleRequest($request);
            if ($form->isSubmitted() && $form->isValid()) {

                $user = $this->getDoctrine()->getRepository("AppBundle:User")->find($this->getUser()->getId());

                $comment = $form->getData();
                $comment->setPerson($user);
                $comment->setReplyTo($replyToId);
                $comment->setPostId($id);
                $comment->setDateAdded(new \DateTime("now"));

                $em = $this->getDoctrine()->getManager();
                $article = $em->getRepository('AppBundle:Article')->find($id);
                $article->setComments($article->getComments() + 1);
                $em->persist($article);
                $em->persist($comment);
                try {
                    $em->flush();
                    $status = "success";
                    $message = "new comment was saved";
                } catch (\Exception $e) {
                    $message = $e->getMessage();
                }
            }
        }

        $response = array(
            'status' => $status,
            'message' => $message,
        );

        return new JsonResponse($response);
    }

    /**
     * @Route("/articles/{category}/{id}/addanswer/{replyToId}", defaults={"replyToId"=0}, name="addanswer")
     */
    public function addAnswer(Request $request, $category, $id, $replyToId)
    {
        $status = 'error';
        $message = '';

        if (!$this->isGranted('ROLE_USER')) {
            echo 'ne e lognat'; exit;
            $message = 'Трябва да се логнете, за да добавите нов отговор!';
        } else {
            $comment = new Comment();
            $comment->setContent($request->request->get('textarea-answer'));
            $comment->setPersonId($this->getUser()->getId());
            $comment->setReplyTo($replyToId);
            $comment->setPostId($id);
            $comment->setDateAdded(new \DateTime("now"));

            $em = $this->getDoctrine()->getManager();
            $em->persist($comment);
            try {
                $em->flush();
                $status = "success";
                $message = "new answer was saved";
            } catch (\Exception $e) {
                $message = $e->getMessage();
            }
        }

        $response = array(
            'status' => $status,
            'message' => $message,
        );

        return new JsonResponse($response);
    }

    /**
     * @Route("/articles/{category}/{id}/true/{page}", defaults={"page"=1}, name="articleAjax")
     */
    public function getArticleAjax($category, $id, $page)
    {
        $recordsPerPage = 10;
        $offset = ($page-1) * $recordsPerPage;

        $commentRepo = $this->getDoctrine()->getRepository(Comment::class);

        $countRecords = $commentRepo->countRecords($id);
        $totalPages = ceil($countRecords / $recordsPerPage);

        $articleRepo = $this->getDoctrine()->getRepository(Article::class);
        $article = $articleRepo->find($id);

        $comments = $commentRepo->getPaginationPost($recordsPerPage, $offset, $id);

        foreach ($comments as &$comment) {
            $subcomments = $commentRepo->getSubComments($comment['id']);
            $comment['subComments'] = $subcomments;
        }

        $response = [
            'comments' => $comments,
            'id' => $id,
            'totalPages' => $totalPages
        ];

        return new JsonResponse($response);
    }

    /**
     * @Route("subcomments/{commentId}/{lastAnswer}/{step}", defaults={"step"=2}, name="getSubcomments")
     */
    public function getMoreAnswers($commentId, $lastAnswer, $step)
    {
        $limit = 2;
        $commentRepo = $this->getDoctrine()->getRepository(Comment::class);
        $answers = $commentRepo->getMoreAnswers($commentId, $lastAnswer, $step, $limit);

        $step = $step+2;

        $response = [
            'answers' => $answers,
            'step' => $step
        ];

        return new JsonResponse($response);

    }

    /**
     * @Route("/articles/{category}/{id}/addtofavorites", name="addToFavourites")
     */
    public function addToFavourites($category, $id)
    {
        $em = $this->getDoctrine()->getManager();
        $article = $em->getRepository("AppBundle:Article")->find($id);
        $user = $this->getUser();
        $user = $em->getRepository("AppBundle:User")->find($user->getId());
        if (!$user->addFavouriteArticle($article)) {
            $article->setFavourites($article->getFavourites() - 1);
        } else {
            $article->setFavourites($article->getFavourites() + 1);
        }
        $em->persist($article);
        $em->persist($user);
        $em->flush();

        $test = 'true';

        return new JsonResponse($test);
    }

    /**
     * @Route("/articles/{category}/{id}/likeunlike/{type}", name="likeUnlike")
     */
    public function likeUnlikeAction($category, $id, $type)
    {
        $isLikedUnliked = false;

        $type == 'like' ? $otherType = 'unlike' : $otherType = 'like';

        $em = $this->getDoctrine()->getManager();
        $article = $em->getRepository("AppBundle:Article")->find($id);

        $user = $this->getUser();
        $user = $em->getRepository("AppBundle:User")->find($user->getId());

        $UserLikedArticle = $em->getRepository('AppBundle:UserLikedArticles')
            ->findOneBy(array(
                'userId' => $user,
                'articleId' => $article,
                'appraisal' => $type
            ));

        $userOtherTypeLikedArticle = $em->getRepository('AppBundle:UserLikedArticles')
            ->findOneBy(array(
                'userId' => $user,
                'articleId' => $article,
                'appraisal' => $otherType
            ));

        if ($type == 'like') {
            if ($UserLikedArticle) {
                $em->remove($UserLikedArticle);
                $em->flush();
                $article->setLikes($article->getLikes() - 1);
            } else {
                $userLikedArticles = new UserLikedArticles();
                $userLikedArticles->setUserId($user);
                $userLikedArticles->setArticleId($article);
                $userLikedArticles->setAppraisal($type);
                $article->setLikes($article->getLikes() + 1);

                if ($userOtherTypeLikedArticle) {
                    $em->remove($userOtherTypeLikedArticle);
                    $article->setLikes($article->getLikes() + 1);
                }

                $em->persist($userLikedArticles);
                $em->flush();
                $isLikedUnliked = true;
            }

        } else {
            if ($UserLikedArticle) {
                $em->remove($UserLikedArticle);
                $em->flush();
                $article->setLikes($article->getLikes() + 1);
            } else {
                $userLikedArticles = new UserLikedArticles();
                $userLikedArticles->setUserId($user);
                $userLikedArticles->setArticleId($article);
                $userLikedArticles->setAppraisal($type);
                $article->setLikes($article->getLikes() - 1);

                if ($userOtherTypeLikedArticle) {
                    $em->remove($userOtherTypeLikedArticle);
                    $article->setLikes($article->getLikes() - 1);
                }

                $em->persist($userLikedArticles);
                $em->flush();
                $isLikedUnliked = true;
            }
        }

        $em->persist($article);
        $em->flush();

        $likes = $article->getLikes();

        return new JsonResponse($likes);

    }
}

JS:

$( document ).ready(function() {

    loadComments(window.location.href + '/true', '', '');

    //Add / Remove Favourties
    $(".heart.fa").click(function() {

        var url = $('#add-favourite-button').data('link');

        $.ajax({
            type: "POST",
            url: url,
            success: function(data)
            {
                $('#add-favourite-button').toggleClass("fa-heart fa-heart-o");
            }
        });


    });

    //Like / Unlike
    $(".glyphicon-arrow-up, .glyphicon-arrow-down").click(function () {

        var button = $(this);
        var type = button.attr("data-type");
        var url = window.location.href + '/likeunlike/' + type;

        $.ajax({
            type: "POST",
            url: url,
            success: function(data)
            {
                if (button.attr('id') == 'button-like-article') {
                    $("#button-like-article").toggleClass("orange-arrow");
                    $('#button-unlike-article').removeClass("orange-arrow");
                } else {
                    $("#button-unlike-article").toggleClass("orange-arrow");
                    $("#button-like-article").removeClass("orange-arrow");
                }
                $('#likes-count').text(data);
            }
        });
    });


    // Send comment client logic
    $("#comment_box").submit(function(e) {
        e.preventDefault();
        var form = $(this);
        var url = form.attr('action');

        var category = url.split('/')[2];
        var article = url.split('/')[3];

        $.ajax({
            type: "POST",
            url: url,
            data: form.serialize(),
            success: function(data)
            {
                loadComments('', category, article);
            }
        });
    });

    // Send answer client logic
    $(document).on("click", "#saveButtonAnswer", function (e) {
        $(".answer_box").submit(function(e) {
            e.preventDefault();
            var form = $(this);
            var url = form.attr('action');

            $.ajax({
                type: "POST",
                url: url,
                data: form.serialize(),
                success: function(data)
                {
                    loadComments(window.location.href + '/true', '', '');
                }
            });
            });
    });

    // Show / Hide form for comment
    $(document).on("click", ".reply", function (e) {
        e.preventDefault();
        var commentId = $(this).attr('href');
        $("#post-comment"+commentId).toggle();
    });

    // Show More answers client logic
    $(document).on("click", ".show-more-answers", function (e) {
        e.preventDefault();
        url = $(this).attr('href');
        console.log(url)    ;
        id = $(this).attr('id');
        commentId = $(this).attr('data-comment-id');
        $.ajax({
            type: "GET",
            url: url,
            success: function(data)
            {
                var html = '';

                var answersArray = Object.keys(data.answers).map(function(key) {
                    return data.answers[key];
                });

                console.log(answersArray);

                for (var i = 0; i < answersArray.length; i++) {
                    html += '<div>' +
                        '<div class="media comment-area">' +
                        '<div class="media-left">' +
                        '<a href="#">' +
                        '<img class="media-object" src="../../images/testimonial-1.jpg" alt="">' +
                        '</a>' +
                        '</div>' +
                        '<div class="media-body">' +
                        '<a class="media-heading" href="#">Prodip Ghosh</a>' +
                        '<h5>Oct 18, 2016</h5>' +
                        '<p>' + answersArray[i].content + '</p>' +
                        '</div>';

                            if ((answersArray[answersArray.length - 1] === answersArray[i])) {
                                html += '<a href="/subcomments/' + commentId + '/' + answersArray[i].id + '/' + data.step + '" class="show-more-answers" id="show-more-answers' + answersArray[i].id + '" data-comment-id="' + commentId + '">Show More</a>';
                            }

                    html += '</div>';
                }

                $('#'+id).after(html);
                $('#'+id).remove();
            }
        });
    });

    $(document).on("click", "#pagination-link", function (e) {
        e.preventDefault();
        var url = $(this).attr('href');
        loadComments(url);
    });

    // Send comment client logic
    function loadComments (url = '', category = '', article = '', step = 1) {
        var html = '';
        url = (url != '' ? url : '/articles/' + category + '/' + article + '/true');

        $.ajax({
            type: "GET",
            url: url,
            success: function(data)
            {
                var image = "../../images/testimonial-4.jpg";
                data.comments.forEach(function(comment) {
                    html +=
                    '<div class="comment_area">' +
                        '<div class="media">' +
                        '<div class="media-left">' +
                            '<a href="#">' +
                                '<img class="media-object" src="' + image + '" alt="">' +
                            '</a>' +
                        '</div>' +
                    '<div class="media-body" id="comment-div">' +
                        '<a class="media-heading" href="/profile/' + comment.person.id + '">' + comment.person.firstName + '</a>' +
                        '<h5>Oct 18, 2016</h5>' +
                        '<p>' + comment.content + '</p>' +
                        '<a class="reply" href="' + comment.id + '">Отговори</a>' +
                    '</div>' +
                    '<div class="post_comment" id="post-comment' + comment.id + '" style="display: none;">' +
                        '<h3>Добави отговор</h3>' +
                        '<form method="POST" class="comment_box answer_box" id="answer-form' + comment.id  + '" action="' + data.id + '\\addanswer\\' + comment.id + '") }}">' +
                            '<textarea id="textarea-answer" name="textarea-answer" class="form-control input_box"></textarea>' +
                            '<button type="submit" id="saveButtonAnswer">Изпрати</button>' +
                        '</form>' +
                    '</div>' +
                    '</div>' +
                    '</div>';

                    var subcommentsArray = Object.keys(comment.subComments).map(function(key) {
                        return comment.subComments[key];
                    });
                    var limit = 2;

                    if (subcommentsArray.length > 0) {
                        //var lastSubcomment = subcommentsArray[subcommentsArray.length - 1];
                            for (var i = 0; i < limit; i++) {
                                if (typeof subcommentsArray[i] === 'undefined') {
                                    continue;
                                }
                                html += '<div class="comment_area reply_comment">' +
                                    '<div class="media comment-area">' +
                                        '<div class="media-left">' +
                                            '<a href="#">' +
                                            '<img class="media-object" src="../../images/testimonial-1.jpg" alt="">' +
                                            '</a>' +
                                        '</div>' +
                                        '<div class="media-body">' +
                                            '<a class="media-heading" href="#">' + subcommentsArray[i].person.firstName + '</a>' +
                                            '<h5>Oct 18, 2016</h5>' +
                                            '<p>' + subcommentsArray[i].content + '</p>' +
                                        '</div>' +
                                    '</div>';
                                    if (subcommentsArray.length > limit) {
                                        if (subcommentsArray[limit-1] === subcommentsArray[i]) {
                                            html += '<a href="/subcomments/' + comment.id + '/' + subcommentsArray[i].id + '" class="show-more-answers" id="show-more-answers' + subcommentsArray[i].id + '" data-comment-id="' + comment.id + '">Show More</a>'
                                        }
                                    }
                                html += '</div>';

                            }
                    }
                });

                html += '<ul>';
                for (var i = 1; i <= data.totalPages; i ++) {
                    html += '<li><a href="' + data.id + '/true/' + i + '" id="pagination-link">' + i +'</a></li>';
                }
                html += '</ul>';

                $('.testt').html(html);
            }
        });
    }
});

View:

{% extends 'base.html.twig' %}

{% block body %}
    {% include 'home/header.html.twig' %}

    <!-- Banner area -->
    <section class="banner_area" data-stellar-background-ratio="0.5">
        <h2>Our Blog</h2>
        <ol class="breadcrumb">
            <li><a href="index.html">Home</a></li>
            <li><a href="#" class="active">Blog</a></li>
        </ol>
    </section>
    <!-- End Banner area -->

    <!-- blog area -->
    <section class="blog_all">
        <div class="container">
            <div class="row m0 blog_row">
                <div class="col-sm-8 main_blog">
                    <img src="images/blog/blog_hed-1.jpg" alt="">
                    <div class="col-xs-1 p0">
                        <div>
                            <button id="button-like-article" class="glyphicon glyphicon-arrow-up {{ isLikedArticle ? 'orange-arrow' : '' }}" data-type="like"></button>
                            <p id="likes-count">{{ article.likes }}</p>
                            <button id="button-unlike-article" class="glyphicon glyphicon-arrow-down {{ isUnlikedArticle ? 'orange-arrow' : '' }}" data-type="unlike"></button>
                        </div>
                        <div class="blog_date">
                            <a href="#">{{ article.dateAdded|date("d") }}</a>
                            <a href="#">{{ article.dateAdded|date("M")|cyrillicMonth }}</a>
                        </div>
                        {% if is_granted('ROLE_USER') %}
                            <div>
                                <i class="{{ isFavourite ? 'heart fa fa-heart' : 'heart fa fa-heart-o' }}" id="add-favourite-button" data-link="{{ path('addToFavourites', {'category':article.category.code, 'id':article.id}) }}"></i>
                            </div>
                        {% endif %}
                    </div>
                    <div class="col-xs-11 blog_content">
                        <a class="blog_heading" href="#">{{ article.title }}</a>
                        <a class="blog_admin" href="#"><i class="fa fa-user" aria-hidden="true"></i>{{ article.author }}</a>
                        <ul class="like_share">
                            <li><a href="#"><i class="fa fa-comment" aria-hidden="true"></i>{{ article.comments }}</a></li>
                            <li><a href="#"><i class="fa fa-heart" aria-hidden="true"></i>{{ article.favourites }}</a></li>
                            <li><a href="#"><i class="fa fa-share-alt" aria-hidden="true"></i></a></li>
                        </ul>
                        <p>{{ article.content }}</p>
                        <!--div class="tag">
                            <h4>TAG</h4>
                            <a href="#">PAINTING</a>
                            <a href="#">CONSTRUCTION</a>
                            <a href="#">PAINTING</a>
                        </div-->
                    </div>
                    <div class="client_text" id="client-text">
                        <img class="img-circle" src="images/testimonial-4.jpg" alt="">
                        <a class="client_name" href="#">Emran Khan</a>
                        <p>Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.</p>
                        {% if previousArticle is not null and nextArticle is not null %}
                            <a class="control button_all" href="{{ path('article', {'category':previousArticle.category.code, 'id':previousArticle.id}) }}"><i class="fa fa-long-arrow-left" aria-hidden="true"></i> {{ previousArticle.title }}</a>
                            <a class="control button_all" href="{{ path('article', {'category':nextArticle.category.code, 'id':nextArticle.id}) }}">{{ nextArticle.title }} <i class="fa fa-long-arrow-right" aria-hidden="true"></i></a>
                        {% endif %}
                    </div>
                    <div class="testt">

                    </div>
                    <div class="post_comment">
                        <h3>Добави коментар</h3>
                        {{ form_start(commentForm, {'action': path('addcomment', {'category':article.category.code, 'id':article.id})}) }}
                            <div class="col-md-12">
                                <h4>{{ form_label(commentForm.content) }}</h4>
                                {{ form_widget(commentForm.content) }}
                                {{ form_widget(commentForm.submit) }}
                            </div>
                        {{ form_end(commentForm) }}
                    </div>
                </div>
                <div class="col-sm-4 widget_area">
                    <div class="resent">
                        <h3>Последни теми:</h3>
                        {% for article in lastArticles %}
                        <div class="media">
                            <div class="media-left">
                                <a href="{{ path('article', {'category':article.category.code, 'id':article.id}) }}">
                                    <img class="media-object" src="images/blog/rs-1.jpg" alt="">
                                </a>
                            </div>
                            <div class="media-body">
                                <a href="">{{ article.title }}</a>
                                <h6>{{ article.dateAdded|date("M")|cyrillicMonth }} {{ article.dateAdded|date("d") }}, {{ article.dateAdded|date("Y") }}</h6>
                            </div>
                        </div>
                        {% endfor %}
                    </div>
                    <div class="resent">
                        <h3>Категории</h3>
                        <ul class="architecture">
                            {% for category in categories %}
                                <li><a href="{{ path('articles', {'category':category.code}) }}"><i class="fa fa-arrow-right" aria-hidden="true"></i>{{ category.name }}</a></li>
                            {% endfor %}
                        </ul>
                    </div>
                    <!--div class="resent">
                        <h3>ARCHIVES</h3>
                        <ul class="architecture">
                            <li><a href="#"><i class="fa fa-arrow-right" aria-hidden="true"></i>February 2016</a></li>
                            <li><a href="#"><i class="fa fa-arrow-right" aria-hidden="true"></i>April 2016</a></li>
                            <li><a href="#"><i class="fa fa-arrow-right" aria-hidden="true"></i>June 2016</a></li>
                        </ul>
                    </div-->
                    <div class="search">
                        <input type="search" name="search" class="form-control" placeholder="Search">
                    </div>
                    <!--div class="resent">
                        <h3>Tag</h3>
                        <ul class="tag">
                            <li><a href="#">PAINTING</a></li>
                            <li><a href="#">CONSTRUCTION</a></li>
                            <li><a href="#">Architecture</a></li>
                            <li><a href="#">Building</a></li>
                            <li><a href="#">Design</a></li>
                            <li><a href="#">Design</a></li>
                        </ul>
                    </div-->
                </div>
            </div>
        </div>
    </section>
    <!-- End blog area -->

    {% include 'home/footer.html.twig' %}
{% endblock %}

Any advice is welcome!

\$\endgroup\$
0
\$\begingroup\$

Overall, the methods and functions look a bit long. Look at ArticleController::getArticle() - its more than 50 lines! Pretend you are a teammate who has to modify this code without being very familiar with it. One way to improve things would be to split out blocks of code into separate methods - especially repeated code like the blocks that instantiate and save Comment objects. This adheres to the Don't Repeat Yourself principle (i.e. D.R.Y). You might also aim to keep the indentation level to one and avoid using the else keyword, as recommended by Rafael Dohms in this presentation about cleaning up code.


I see a lot of DOM lookups throughout the various javascript event handlers. Bear in mind that those are not cheap1 so it is better to store DOM lookups in a variable (or constant if is used - see last section below for more information).


Is there really only one element with the class testt? Would there ever be a case where multiple elements with that class would be appropriate? If not, perhaps an id attribute should be used instead (including referencing that element in the JavaScript code).


I can't tell which version of jQuery is used but as of version 3.02 the following syntax is deprecated:

$( document ).ready(function() {

and can be shortened to

$(function() {

Some places in the JavaScript could be simplified using partially applied functions- e.g.:

success: function(data)
            {
                loadComments(window.location.href + '/true', '', '');
            }

could be simplified to something like:

success: loadComments.bind(null, window.location.href + '/true', '', '')

It appears that there are default parameters used on one JavaScript function definition:

function loadComments (url = '', category = '', article = '', step = 1) {

This is a feature of , which means if you are going to use that standard, then you could start using other features like const and let instead of var for scoping variables, arrow functions, etc.

1https://channel9.msdn.com/Events/MIX/MIX09/T53F
2https://api.jquery.com/ready/

\$\endgroup\$

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.