Roitko
Roitko

Reputation: 127

JS: HTML is not dynamically changing

I am building an web that allows user to like a post when they click a button. CreateLike function calls API and creates a like object however, I would like to have the number of likes updated right away without reloading. I built another API that returns the number of likes for a post. Function LikeCount should put the number of likes into the p tag. It works initially when I load the page however, the value does not change when I click the button even though I can see that the API is called. (After reloading the page the number changes as expected) What am I doing wrong?

I have this HTML:

<p class="like-count" id={{post.id}}></p>
<script>LikeCount({{post.id}});</script>
<button type="button" class="btn-like" onclick="CreateLike({{user.id}},{{post.id}})"></button>

with JS functions:

            function CreateLike (userid,postid) {
                xhr = new XMLHttpRequest();
                var url = "{% url 'likes' %}";
                var csrftoken = getCookie('csrftoken')
                xhr.open("POST", url, true);
                xhr.setRequestHeader("X-CSRFToken",'{{ csrf_token }}')
                xhr.setRequestHeader("Content-type", "application/json");
                xhr.onreadystatechange = function () { 
                    if (xhr.readyState == 4 && xhr.status == 200) {
                        var json = JSON.parse(xhr.responseText);
                        console.log(json.email + ", " + json.name)
                    }
                }
                var data = JSON.stringify({csrfmiddlewaretoken:csrftoken,"user":userid,"post":postid});
                xhr.send(data);
                LikeCount(postid);
            }
            function LikeCount(postid) {
                var xmlhttp = new XMLHttpRequest();
                var url = "{% url 'likecount' id=112233 %}".replace("112233", postid);

                xmlhttp.onreadystatechange = function() {
                    if (this.readyState == 4 && this.status == 200) {
                    var myArr = JSON.parse(this.responseText);
                    myFunction(myArr);
                    }
                };
                xmlhttp.open("GET", url, true);
                xmlhttp.send();

                function myFunction(arr) {
                    var out = arr.like_count;
                    document.getElementById(postid).innerHTML = out;
                }
            }

Like count API looks like this:

{
    "like_count": 1
}

Upvotes: 0

Views: 69

Answers (2)

Roitko
Roitko

Reputation: 127

Added

xhr.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 201) {
    var myArr = JSON.parse(this.responseText);
    LikeCount(myArr.post);
    }
};

before

xhr.send(data); 

and it fixed the issue.

Upvotes: 0

ABGR
ABGR

Reputation: 5205

if(xhr.readyState === XMLHttpRequest.DONE) {
    var status = xhr.status;
    if (status === 0 || (status >= 200 && status < 400)) {
     LikeCount(); //Put your get like count here
    } else {
      // Handle Errors
    }
  }

Call LikeCount only after receiving the response of your POST request. Right now you're immediately sending a GET request without ensuring if the previous POST request got completed.

Upvotes: 1

Related Questions