-1

I've started on my first AJAX project and i am attempting to write double AJAX function where the output string ("venue_ID") of the first function is used by second AJAX function to output a string (img_Url). But I haven't had any success. Any suggestion for my code below would be much appreciated;

$(function (){
var api_url = 'https://api.foursquare.com/v2/venues/search?ll=4.89996,114.928457&client_id=DKVNHNM2I15Y0TF1RNAEF1FPQHJPCCUPHBMJKGFHXUQITWHC&client_secret=XLCPTHFDAVNTUUAOCMNDQLWAS4TXZOGAXV5A2L1AAK5QNJZS&v=20131016&query=bake+culture';
var $info = $('#info');

$.ajax({
    type: 'GET',
    url: api_url,
    data: {format: 'json'},
    dataType: 'json',
    success: function (info) {
        var response = info.response.venues[0];
        var venue_id = response.id;
        console.log('success', info);

        $info.append(venue_id);
        var $pic = $('#pic');

        var baseUrl = 'https://api.foursquare.com/v2/venues/';
        var fsParam = '/?client_id=DKVNHNM2I15Y0TF1RNAEF1FPQHJPCCUPHBMJKGFHXUQITWHC&client_secret=XLCPTHFDAVNTUUAOCMNDQLWAS4TXZOGAXV5A2L1AAK5QNJZS&v=20131016';
        var picUrl = baseUrl + venue_id + fsParam;

        $.ajax({
            type: 'GET',
            url: picUrl,
            data: {format: 'json'},
            dataType: 'json',
            success: function (pic) {
                var venue_data = pic.response.venue;
                var img_url = venue_data.bestPhoto.prefix + '192x144' + venue_data.bestPhoto.suffix;
                console.log('success', pic);

                $pic.append(img_url);
            }
        });
    }
});
});
<html lang='en'>
  <head>
    <title>AJAX Demo</title>
  </head>
  <body>
    <div>
      <h4>AJAX Demo</h4>
      <div id="info"></div> <!-- To test 1st AJAX output -->
      <div id="pic"></div>
    </div>
    <div><img src="pic"></div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script type="text/javascript" src="js/source.js"></script>
</body>
</html>
G.Goh
  • 41
  • 2
  • 6
  • `var venue_id` is only defined in the callback, so it won't be accessable outside. But even if you fix that, it will still not work, because ajax requests are async. – t.niese Dec 02 '17 at 18:03
  • Possible duplicate of [Why is my variable unaltered after I modify it inside of a function? - Asynchronous code reference](https://stackoverflow.com/questions/23667086/why-is-my-variable-unaltered-after-i-modify-it-inside-of-a-function-asynchron) – t.niese Dec 02 '17 at 18:03
  • Possible duplicate of [How do I access previous promise results in a .then() chain?](https://stackoverflow.com/questions/28250680/how-do-i-access-previous-promise-results-in-a-then-chain) – Roamer-1888 Dec 02 '17 at 20:14

2 Answers2

0

Your code doesn't work for two reasons:

  1. The variable venue_id is defined in the scope of the Ajax callback function, it is undefined outside of the function
  2. The Ajax call is executed asynchronously, i.e. the code after the $.ajax statement is executed immediately, before the venue ID has been returned from the Ajax call.

There are various ways to tackle this and plenty of related questions on Stack Overflow. The easiest fix in your case would be to move the second Ajax call inside the first Ajax call's callback function, like this:

$(function (){
    var api_url = 'https://api.foursquare.com/v2/venues/search?ll=4.89996,114.928457&client_id=DKVNHNM2I15Y0TF1RNAEF1FPQHJPCCUPHBMJKGFHXUQITWHC&client_secret=XLCPTHFDAVNTUUAOCMNDQLWAS4TXZOGAXV5A2L1AAK5QNJZS&v=20131016&query=bake+culture';
    var $info = $('#info');

    $.ajax({
        type: 'GET',
        url: api_url,
        data: {format: 'json'},
        dataType: 'json',
        success: function (info) {
            var response = info.response.venues[0];
            var venue_id = response.id;
            console.log('success', info);

            $info.append(venue_id);
            var $pic = $('#pic');

            var baseUrl = 'https://api.foursquare.com/v2/venues/';
            var fsParam = '/?client_id=DKVNHNM2I15Y0TF1RNAEF1FPQHJPCCUPHBMJKGFHXUQITWHC&client_secret=XLCPTHFDAVNTUUAOCMNDQLWAS4TXZOGAXV5A2L1AAK5QNJZS&v=20131016';
            var picUrl = baseUrl + venue_id + fsParam;

            $.ajax({
                type: 'GET',
                url: picUrl,
                data: {format: 'json'},
                dataType: 'json',
                success: function (pic) {
                    var venue_data = pic.response.venue;
                    var img_url = venue_data.bestPhoto.prefix + '192x144' + venue_data.bestPhoto.suffix;
                    console.log('success', pic);

                    $pic.append(img_url);
                }
            });
        }
    });
});
Patrick Hund
  • 19,163
  • 11
  • 66
  • 95
0
  1. There are several ways to tackle the asynchronous issue.

a/ The native way in JS is to have nested callback function calls. Refer to XMLHttpRequest() objects as a reference, as well as their onreadystatechange property.

Once you get a better understanding of the native API calls in JS, you can use the shortcuts provided by jQuery, promises or async/wait. All of this is well documented on Stack Overflow and other websites.

b/ If you decide to use jQuery you will need to next your second AJAX call within the 1st one, that is inside the instructions that follow a successful call on the first AJAX. This structure is called "nested".

c/ Lastly you can use the tools provided by async/wait.

  1. Your variable venue_id should be defined as a global variable outside of any function, so that it can be used in another function. But if you use nested callbacks you should have no issue with this, and no need of a global variable.
edmond
  • 1,432
  • 2
  • 15
  • 19
  • Thanks Tristan. I've Googled item 1 & 2. Got a grasp of nested function thanks for @Patrick Hund. Still trying to wrap my head around XMLHttpRequest(). Perhaps I'm still trying to familiar with the JS terminologies. Fortunately, I have discovered the use of "var $pic = $('#pic');" as a global declaration for HTML use. But the image output came up blank via "
    . Is it because it is not the correct format for not in plan format?
    – G.Goh Dec 03 '17 at 07:11