Mardymar
Mardymar

Reputation: 419

How to run a function asynchronously (XMLHttpRequest)

I am loading data from an api and I need to run a function once the code is loaded.

function make(query, callback){
    console.log("1");
    var results = makeRequest(query);
    return callback(results);
};

setPoints = function(results){
    console.log("2");
    for(var key in results)
    {
        console.log("3");
        var myLatLng = {lat: key.lat, lng: key.lon};
        var marker = new google.maps.Marker({
            position: myLatLng,
            map: map,
            title: 'Hello World!'
        });
    }
};

make(3, setPoints);

makeRequest = function(place) {
    var req = new XMLHttpRequest();
    req.open('GET', "https://trailapi-trailapi.p.mashape.com/?limit=25&q[city_cont]=San+Luis+Obispo&radius=205", true);
    req.setRequestHeader('X-Mashape-Key', 'JwTKoEqkTbmsh3eqT0fBweCHYIAUp1h1GCbjsnkh59Bok0iqOC');
    req.onreadystatechange = function () {
        if (req.readyState === 4) {
            if (req.status >= 200 && req.status < 400) {
                var response = JSON.parse(req.responseText);
                var latLongs = response.places.map(function (key) {
                    return {lat: key.lat, lon: key.lon};
                });
                console.log("Returned");
                return latLongs;
            } else {
                alert("Failed to load " + req.status);
                return null;
            }
        }
    };
    req.send();
}

I would like for the code to log "1, returned, 2, 3". Instead it is logging "1, 2, returned".

Upvotes: 0

Views: 64

Answers (1)

caballerog
caballerog

Reputation: 2739

The solution is pass the callback to the function makeRequest. This callback is running after XMLHttpRequest is completed.

function make(query, callback){
    console.log("1");
    makeRequest(query,callback);

};

setPoints = function(results){
    console.log("2");
    for(var key in results)
    {
        console.log("3");
        var myLatLng = {lat: key.lat, lng: key.lon};
        var marker = new google.maps.Marker({
            position: myLatLng,
            map: map,
            title: 'Hello World!'
        });
    }
};

make(3, setPoints);
makeRequest = function(place, callback) {
    var req = new XMLHttpRequest();
    req.open('GET', "https://trailapi-trailapi.p.mashape.com/?limit=25&q[city_cont]=San+Luis+Obispo&radius=205", true);
    req.setRequestHeader('X-Mashape-Key', 'JwTKoEqkTbmsh3eqT0fBweCHYIAUp1h1GCbjsnkh59Bok0iqOC');
    req.onreadystatechange = function () {
        if (req.readyState === 4) {
            if (req.status >= 200 && req.status < 400) {
                var response = JSON.parse(req.responseText);
                var latLongs = response.places.map(function (key) {
                    return {lat: key.lat, lon: key.lon};
                });
                console.log("Returned");
                return callback(latLongs);
            } else {
                alert("Failed to load " + req.status);
                return null;
            }
        }
    };
    req.send();
}

Another horrible solution in your problem is to do the function makeRequest synchronous.

In the method XMLHttpRequest.open you define the AJAX a/synchronous function in the third parameter (only should change the value true to false).

makeRequest = function(place) {
    var req = new XMLHttpRequest();
    req.open('GET', "https://trailapi-trailapi.p.mashape.com/?limit=25&q[city_cont]=San+Luis+Obispo&radius=205", false);
    req.setRequestHeader('X-Mashape-Key', 'JwTKoEqkTbmsh3eqT0fBweCHYIAUp1h1GCbjsnkh59Bok0iqOC');
    req.onreadystatechange = function () {
        if (req.readyState === 4) {
            if (req.status >= 200 && req.status < 400) {
                var response = JSON.parse(req.responseText);
                var latLongs = response.places.map(function (key) {
                    return {lat: key.lat, lon: key.lon};
                });
                console.log("Returned");
                return latLongs;
            } else {
                alert("Failed to load " + req.status);
                return null;
            }
        }
    };
    req.send();
}

Upvotes: 2

Related Questions