4

I have this XMLHttpRequest and I want to print the variable contents... But outside function onload the variable contents is "". How I can access the variable outside the function?

var xhr = new XMLHttpRequest();
var contents = ""
xhr.open("GET", fileURL);
xhr.responseType = "arraybuffer";
xhr.onload = function () {
    if (this.status === 200) {
        var blob = new Blob([xhr.response], {type: "application/pdf"});
        var objectUrl = URL.createObjectURL(blob);
        alert("sucess")

        var reader = new FileReader();
        reader.readAsBinaryString(blob);
        reader.onload = function(e) {
            contents = e.target.result;
        }
    }
    else {
    alert("insucess");
    }
};
xhr.send();


console.log(contents);
PRVS
  • 1,612
  • 4
  • 38
  • 75
  • This seems to be applicable: http://stackoverflow.com/questions/5485495/how-can-i-take-advantage-of-callback-functions-for-asynchronous-xmlhttprequest – mariocatch Nov 08 '15 at 14:49
  • Wait for the asynchronous xhr to finish – Jaromanda X Nov 08 '15 at 14:50
  • 2
    A variation of this question is asked many times a day here. Your XHR call is asynchronous. That means the response happens sometime AFTER the rest of your code has executed. Therefore, the ONLY place you can reliably use the results is INSIDE the `onload` handler or in a function you call from there and pass the result to. You cannot use the result synchronously where your `console.log()` statement is. Welcome to the world of asynchronous programming. You must write the code differently. See the question yours is marked a dup of for many other explanations. – jfriend00 Nov 08 '15 at 15:05

1 Answers1

3

A better option is to execute a function with the response as a callback.

A quick example:

var createXhrRequest = function( httpMethod, url, callback ) {

    var xhr = new XMLHttpRequest();
    xhr.open( httpMethod, url );

    xhr.onload = function() {
        callback( null, xhr.response );
    }; 

    xhr.onerror = function() {
        callback( xhr.response );
    };

    xhr.send();

}

createXhrRequest( "GET", fileUrl, function( err, response ) {

    // Do your post processing here. 
    if( err ) { console.log( "Error!" ); }

    // This is just basic code; you can modify it to suit your needs.

});

Remember, using async is better than using a Hacked-Sync method.

EDIT 1: Based on what you want

That is something you shouldn't do. I got what you're trying to say; for that, you'll need sync XMLHttpRequests which aren't advisable.

Remember the way Async (threading) works on PARALLEL threads, so any async activity will have its own thread, rather than working on the same thread.

But again, I'll recommend async requests. A great way to do it is to use the Promises.js Library availble at https://www.promisejs.org/

In simple terms, you can't do that easily.

weirdpanda
  • 2,521
  • 1
  • 20
  • 31
  • But I don't understand, how can I put my "contents" variable instead of a function ? I need this on variable. – PRVS Nov 08 '15 at 14:59
  • But I can't understand how to read a PDF by URL and make all of the "responsetype" for example in my code above... In this library :\ – PRVS Nov 08 '15 at 16:07
  • You can parse the response as you did before. This is just boilerplate. Add all the attributes you want in the function, then access the PDF as the response. Got it, or still confusing? – weirdpanda Nov 08 '15 at 16:11
  • Still confusing ! :S But with your example? And I can put the response on a variable ? I'm very confused. My problem is only the "put on the variable" :S with your example I don't know how can I do that. – PRVS Nov 08 '15 at 16:13
  • You won't be able to access the variable as this is an async call. There are methods, but they are highly inefficient and don't work, sometimes. :\ – weirdpanda Nov 08 '15 at 16:16
  • What you suggest, then? Sync method ? I try but responseType for example is not defined for syncronous. :S I don't know how to make this. I need even the variable for use in another function the response. – PRVS Nov 08 '15 at 16:20
  • Couple that function as the callback. That should do it! :) – weirdpanda Nov 08 '15 at 16:21
  • But how can I make the callback ? On my first xhr function or in the second ? I can't understand how can I make this with a function $(document).ready(function(){...} for example, that is the function that I want. If you can give me a simple example, please. – PRVS Nov 08 '15 at 17:13
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/94542/discussion-between-prvs-and-weirdpanda). – PRVS Nov 08 '15 at 17:18