2

I'm new to javascript, but I can't get my head around this problem. I have a function that upvotes a game:

function upVoteGame(name) {
  $.get("/get_gameValues", function(data) {
    var alreadyExist = false;
    var noVotes = false;
    var games;
    games = data;
    for (var i = 0; i < games.length; i++) {
      if (name === games[i].gameName) {
        alreadyExist = true;


        voteOperations();

        if (userLoggedIn == false) {
          alert("second");
          swal("Cannot post votes", "Please log in or register to vote", "error");
        }

        if (noVotesLeft == false && userLoggedIn == true) {
          $.ajax({
            url: '/editVotes/' + games[i]._id,
            type: 'PUT',
            data: {
              likes: games[i].likes + 1,
              totalVotes: data[i].totalVotes + 1
            },
            success: function(result) {
              alert(games[i].likes + 1);
            }
          });
        }
        refreshGameValues();
        break;
      }
    }

    //This is for us Developers!
    if (!alreadyExist) {
      $.post("/add_game_to_dB", {
        gameName: name
      }, function(result) {
        alert("Introduced " + name);
      });
    }
  });
}

Now I have the function that updates the user's votes left, voteOperations():

function voteOperations() {
  $.get("/users/get_current_user", function(data) {
    //var votes = 5;
    for (var i = 0; i < data.length; i++) {
      votesRemaining = data[i].votesRemaining;
      userLoggedIn = true;
      alert("votes left : " + votesRemaining);

      if ((votesRemaining - 1) < 0) {
        swal("No votes remaining", "Please wait 24 hours to get more votes", "error");
        noVotesLeft = true;
      }
      if (noVotesLeft == false) {
        $.ajax({
          url: '/users/updateUserDetails/' + data[i].user_name,
          type: 'PUT',
          data: {
            votesRemaining: votesRemaining - 1
          },
          success: function(result) {}
        });
      }
    }
  });
}

My problem is a simple problem. In the upVoteGame(name) function, I want the voteOperations() to execute before the if loop below it. However, when I run the code, the if loop below executes first and alerts the user that they are not logged in. When a user logs in, userLoggedIn is set to true, but the if loop executes firsts and tells them that they are not logged in, and then executes the voteOperations() function. I don't know why this is happening. How can I fix this so that voteOperations executes before the if loop?

2
  • Your ajax operation contained in voteOperations is Asynchronous - for a description of what this means, look at this question here. Essentially, this means that $.get will continue to run along side the if statement. Whichever one completes first will be output first. Look at the comment below for a solution. Commented Apr 17, 2018 at 9:58
  • This is because the voteoperations function has a get request which is asynchronous. You will need a callback function where you should include if condition Commented Apr 17, 2018 at 9:58

3 Answers 3

3

This is because the voteoperations function has a get request which is asynchronous. You will need a callback function where you should include if condition

You can try:

function upVoteGame(name) {
  vote(afterGet);
}

afterGet() {
    if condition here
}

function vote(callback) {
    $.get .... {
       //after getting data
       callback();
    }
}
Sign up to request clarification or add additional context in comments.

2 Comments

Possibly paste your comment in to here too, collating the solution with the description would probably be more helpful to future visitors.
@Lewis Thanks... :)
1

You problem occurs due to the asynchronous call of your $.get in the voteOperations function.

Since it is an asynchronous call your code continuous while your $.get is waiting to retrieve data and thus your if statement seems to trigger before your voteOperations function.

In simple words your function actually is triggered before the if statement but before it completes it's result the code continues and triggers your if statement.

You could put your if statement (logic) in the success callback of your vote operation function or use $.ajax with async:false which is not considered a good practice generally but I use it sometimes.

Something like that for example (for the second case)

     $.ajax({
        async: false,
        .....
        success: function (response) {
            //
        }
    });

2 Comments

I see... thanks for the info. I used a setTimeoutFunction for 100ms, which makes sure that the data is retrived, then executes the rest of the code.
@irishSenthil I am afraid this is a very bad idea. You will just end up with a code that depends on the time the response is needed. Every time your backend is a little bit late on his response your code won't work.
0

Asynchronous calls can be handled with jquery function Deffered

function upVoteGame(name) {
    vote().then(doUpVoteGame(), handleError());
}

function doUpVoteGame() {
    ...
}

function handleError(e) {
    console.error("fail", e);
}

function vote() {
    var d = new $.Deferred();     

    $.get .... {
       d.resolve();
    }).fail(function(e) {
       d.reject(e);
    });

    return d;
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.