cneeds
cneeds

Reputation: 319

using ajax context does not resolve scope issue

I am unable to make ajax context work:-

var msgdata = "";
$.ajax({
  type: "POST",
  url: "players/" + joinplayer + "/joingame.php",
  data: { 
    userID: "<?php echo $_SESSION['username']; ?>",
    gameinfo: JSON.stringify(<?php echo json_encode($_SESSION['profile']['user'], true); ?>)
  },
  context: msgdata,
  success: function(data) {
    msgdata = data;
    $.ajax({
      type: "POST",
      url: "renamejoin.php",
      data: { 
        userID: "<?php echo $_SESSION['username']; ?>",
        joinID: joinplayer
      },
      context: msgdata,
      success: function(data) {
        if (data == "" && msgdata != "") {
          // sucessfully joined a player's game
        } else {
            alert(data);
        }
      },
      error: function() {   
        alert(joinplayer + "'s game is no longer available.");
      }
    });
  },
  error: function() {
    alert(joinplayer + "'s game is no longer available.");
  }
});
if (msgdata == "");
  // start showing games awaiting players again
  gamefeedrefresh;
  timer = window.setInterval(gamefeedrefresh, 2500);
}

msgdata is always "" in this final if statement. The problem seems to be a scope issue but even one or both of the context statements make no difference.

Is it possible to resolve this scope issue? All advice appreciated.

Upvotes: 2

Views: 79

Answers (3)

cneeds
cneeds

Reputation: 319

The overall solution wasn't too complex once the asynchonosity was taken into consideration.

The main issue was to make a function for the error exits then waiting for the second success to be triggered to use the msgdata from the first ajax call, which was always in scope but only valid on the second ajax's successful trigger.

The joinfailed function could be inline so that joinplayer would still be in scope but I couldn't decide which error exit to put it on so I decided to keep it separate.

$("#gamefeed").on('click', ".chooseGame", function (evnt) {
  $.ajax({
    type: "POST",
    url: "players/" + joinplayer + "/joingame.php",
    data: { 
      userID: "<?php echo $_SESSION['username']; ?>",
      gameinfo: JSON.stringify(<?php echo json_encode($_SESSION['profile']['user'], true); ?>)
    },
    success: function(data) {
      msgdata = data;
      $.ajax({
        type: "POST",
        url: "renamejoin.php",
        data: { 
          userID: "<?php echo $_SESSION['username']; ?>",
          joinID: joinplayer
        },
        success: function(data) {
          if (data != "") {
            joinfailed(joinplayer);
          } else {
            alert(msgdata); // "you joined joinplayer's game"
            // initialise comms and join the game
          }
        },
        error: function() {   
          joinfailed(joinplayer);
        }
      });
    },
    error: function() {
      joinfailed(joinplayer);
    }
  });
});
function joinfailed(joinplayer) {
  alert(joinplayer + "'s game is no longer available.");
  // start showing games awaiting players again
  gamefeedrefresh;
  timer = window.setInterval(gamefeedrefresh, 2500);
}

Upvotes: 0

Ariel Pepito
Ariel Pepito

Reputation: 659

If you want to force browser to finish execute first the request before continue reading the script, you just add async option in your ajax method and set it to false.

async: false

Upvotes: 0

Andrei Nemes
Andrei Nemes

Reputation: 3122

Ajax requests are asynchronous, meaning the rest of your program will execute before the request comes back. If you want to run code after the request has been completed, move it into the success function body.

You may also want to have a look at Promise.

Upvotes: 3

Related Questions