0

When I call the function with console.log(ip2db()) it prints undefined. How can i return the value returned from ip2db.php?

Here is my code:

function ip2db(){
    var result;
    $.getJSON('https://api.ipgeolocation.io/ipgeo?apiKey=a759dab4af1f462496dda90b3575f7c7', function(data) { 
        var ip_data = JSON.stringify(data, null, 2);
        $.post("https://mywebsite.com/ip2db.php",
            {
                ip_data
            },
            function(data, status){
                console.log("data: " + data + "\nStatus: " + status);
                CreateUserStorage(data);
                result = data;
            }
        );   
    });
    return result;
}
mcan
  • 1,914
  • 3
  • 32
  • 53
  • 4
    Possible duplicate of [How do I return the response from an asynchronous call?](https://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call) – Andreas Nov 02 '18 at 15:42
  • @Andreas Doesn't look like it, OP's console log is placed within the request callback – mxdi9i7 Nov 02 '18 at 15:45
  • @mxdi9i7 _"When i call the function with `console.log(ip2db())` prints `undefined`"_ – Andreas Nov 02 '18 at 15:46
  • The first part of your request went through, and I was able to see the response by logging your ip_data variable. Could you show us the second request url? – mxdi9i7 Nov 02 '18 at 15:46
  • The code looks correct to me, pretty sure its a server problem with your php. – mxdi9i7 Nov 02 '18 at 15:47

2 Answers2

2

ajax call are synchronic calls so you will never get a response. There two options: - passing a callback - use promises

  • there is await - async but off-topic for this question

So in this example you posted, you should do:

function ip2db(your_callback){
    var result;
    $.getJSON('https://api.ipgeolocation.io/ipgeo?apiKey=a759dab4af1f462496dda90b3575f7c7', function(data) { 
        var ip_data = JSON.stringify(data, null, 2);
        $.post("https://mywebsite.com/ip2db.php",
            {
                ip_data
            },
            function(data, status){
                console.log("data: " + data + "\nStatus: " + status);
                CreateUserStorage(data);
                result = data;
                your_callback(result)
            }
        );   
    });
}

you call it like this:

ip2db(function(result) {
    console.log(result);
})
Tzook Bar Noy
  • 11,337
  • 14
  • 51
  • 82
  • 1
    1. _"ajax call are synchronic calls"_ O.o 2. There's already a duplicate, so please close this as duplicate instead of adding another answer for a problem that is posted at least once a day – Andreas Nov 02 '18 at 15:50
  • @Andreas how do I do that? – Tzook Bar Noy Nov 02 '18 at 16:00
1

Tahtakafa, the http methods are async methods, meaning they do not continue flowing with the rest of the code as you would expect in the code you provided above. Thus when you execute ip2db, the value of result at the end of the function is still undefined. However when the response from the server comes the value is set properly. So in order to get the correct value you need to understand async flow in js.

To solve your problem there are several options, but the one thing you need to know is to try to understand async operations in js.

  1. Solution #1: use promises to detect when the response comes and then you can act on that, like so

function ip2db(){
   return new Promise(function(resolve, reject){
      $.getJSON('https://api.ipgeolocation.io/ipgeo?apiKey=a759dab4af1f462496dda90b3575f7c7', function(data) { 
          var ip_data = JSON.stringify(data, null, 2);
          $.post("https://mywebsite.com/ip2db.php",
              {
                  ip_data
              },
              function(data, status){
                  console.log("data: " + data + "\nStatus: " + status);
                  CreateUserStorage(data);
                  result = data;
              }
          );   
      });
   });
}

//use it like this
ip2db().then(function(){
});
  1. With solution 2 you just need leave the code the way it is but don't expect output to be the value of result from the http call. so something like this:

function ip2db(){
  $.getJSON('https://api.ipgeolocation.io/ipgeo?apiKey=a759dab4af1f462496dda90b3575f7c7', function(data) { 
        var ip_data = JSON.stringify(data, null, 2);
        $.post("https://mywebsite.com/ip2db.php",
            {
                ip_data
            },
            function(data, status){
                console.log("data: " + data + "\nStatus: " + status);
                CreateUserStorage(data);
                // make use of result here to do any logic you might want to do
            }
        );   
    });
}
gastonche
  • 463
  • 5
  • 19