0

The following jQuery code attempts to store a client's IP address in a global variable during the callback for an ajax GET request.

Code

  var userip = null;
  $.ajax({
    url: "http://ipinfo.io",
    type: 'get',
    dataType: 'jsonp',
    async: false,
    success: function(data) {
      userip = data.ip;
      console.log(userip); // prints unique ip address
    }
  }).done(console.log(userip)); // prints null

Knowing that GET requests are usually executed asynchronously (but requiring otherwise), I have marked async: false in the JSON spec. For added measure, I call done() to ensure the request has finished before continuing.

Nevertheless, printing userip returns null after the GET request but prints the unique client IP during the ajax success callback.

Any explanation would be greatly appreciated. Thanks in advance.

4
  • The .done function expects a function to callback. The console.log is just being evaluated right away. If you change the parameter of the .done function to be same anonymous function definition that you're using for "success" I think it will work as expected. Commented Jan 18, 2016 at 22:24
  • 2
    You probably shouldnt use async: false,. Instead, look into using the callback correctly or using deferred / returning a promise Commented Jan 18, 2016 at 22:31
  • @DelightedD0D That's absolutely correct and good advice. I'm fairly certain the OP is expecting to to be treated as if the request is occuring in block, i.e. if there was another line after the code shown, it would be executed after the request is complete. Is that correct, @JayDoe? Commented Jan 18, 2016 at 23:02
  • @Mic that's definitely correct! In which case, reading up via the URL posted by DelightedD0D, deferred/promises seem like the best solution I think. Commented Jan 18, 2016 at 23:26

3 Answers 3

1

.done() expects a callback. Try swapping out

console.log(userip)

with

function() { console.log(userip); }
Sign up to request clarification or add additional context in comments.

2 Comments

This works but I don't quite understand why async: false is insufficient to postpone code following the ajax call until after success or failure? Simply executing console.log(userip) after the ajax call also returns null for example. Is this why one needs to use promises/deferred?
@JayDoe If you supply console.log(userip) as an argument, the javascript interpreter will execute it because it's a function call. Just like if you did, for example, console.log(myFunction())... myFunction would execute, and its result would be the argument passed into console.log. The async:false flag in Jquery can't change how the javascript interpreter will inherently evaluate the code.
0

what you're doing is making the console.log(userip) execute immediately, and not after the request is completed. Which is why userip gets stored properly in the success handler. Think of done as what to do once the request is completed. It needs to execute an action (function). You're passing a statement (console.log(userip)) which actually returns undefined. So done doesn't do anything.

try this instead

}).done(function() {
    console.log(userip);
});

Comments

0

Try this

var userip = null;
  $.ajax({
  url: "http://ipinfo.io",
  type: 'get',
  dataType: 'jsonp',
  async: false,
  success: function (data) {
    userip = data.ip;
    console.log(userip); // prints unique ip address
  },
  complete: function () {
    console.log(userip); // prints unique ip address
  }
});

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.