sleeper
sleeper

Reputation: 3496

How to Get Variable from inside a function (used in Ajax call)

Greetings I have an ajax call which:

  1. Gets an xml file of posts
  2. Populates a 2d Array of post info (text and link)

What I need next is to get at the Array to do the next steps, but I cannot get at it.

Scope issue? Ajax issue?

please advise.

// create the link
var posts_href = 'get-posts.php';

// Create XHR Object
function getHTTPObject(){
    var xhr = false;
    // test if standards based
    if (window.XMLHttpRequest) {
        xhr = new XMLHttpRequest();
    }
    else if (window.ActiveXObject) {
        try{
            xhr = new ActiveXObject("Msxml2.XMLHTTP");
        } catch(e) {
            try {
                xhr = new ActiveXObject("Microsoft.XMLHTTP");
            } catch(e){
                xhr = false;
            } 
        }
    }
    return xhr;
}

// Grab File ASYCHRONOUSLY
function grabFile(file){
    // create a new instance of the xhr object
    var request = getHTTPObject();

    // if successful, initiate ajax request
    if(request){
        request.onreadystatechange = function(){
            parseResponseXML(request);

        };

        request.open("GET",file,true);
        request.send(null);
        return true;
    } else {
        return false;
    }
}

// make the ajax call
grabFile(posts_href);

// create the responseXML function
function parseResponseXML(req){
    if(req.readyState == 4){
        if(req.status == 200 || req.status == 304){
            var textArray = [];
            var posts = req.responseXML.getElementsByTagName('post');

            // create array to hold the posts (strings)     
            textArray = new Array(posts.length);

            for(var i=0;i<posts.length;i++){

                var post_text, text, post_link, details_link;

                // get the post info
                post_text = posts[i].getElementsByTagName('text');
                text = post_text[0].firstChild.nodeValue

                post_link = posts[i].getElementsByTagName('details_link');
                if(post_link[0].firstChild != null){
                    details_link = post_link[0].firstChild.nodeValue;
                } else {
                    details_link = "";
                }

                // add post to textArray
                textArray[i] = new Array(text, details_link);
                // console.log(textArray[i]);

            }   // end for..loop                
        }       // end if(req.status)
    }           // end if(req.readyState)   
}               // end parseResponseXML()


// get the value of textArray from the function ->THIS FAILS
console.log(textArray);

Upvotes: 0

Views: 177

Answers (1)

Matt Ball
Matt Ball

Reputation: 360056

Yes, it's an ajax issue. Ajax is asynchronous. Whatever "next steps" that depend on textArray need to be done in the callback. You can modify parseResponseXML to receive an arbitrary callback that it should pass the results array to:

function parseResponseXML(req, callback) {
    // same as original implementation above
    // then,
    callback(textArray);
}

Then you'd use it something like this:

function doAfterParse(textArray) {
    console.log(textArray);
}

// snip...
request.onreadystatechange = function(){
    parseResponseXML(request, doAfterParse);
};

Upvotes: 2

Related Questions