Alfred Huang
Alfred Huang

Reputation: 18235

Load async content within beforeSend of jQuery.ajax

I'm using jQuery to make ajax request.

Before all ajax was sent, I want to read a specific file field, and appends the content to the request data:

<input id="upload" type="file" />

And the script:

$.ajaxSetup({
    beforeSend: function(xhr, settings) {
        var file = document.getElementById('upload');
        if(file.files.length > 0) {
            var reader = new FileReader();
            reader.onload = function(e) {
                settings.data += '&file=' + btoa(e.target.result);
            }
            reader.readAsText();
        }
    }
});

The problem is, the ajax request is sent immediately when I call the reader.readAsText(), and don't wait until the content was loaded, so the data changing is not guaranteed to complete, or saying, never.

So is there anything to delay the sending action until the read operation finishes, or make the reading action synchronous?

Upvotes: 3

Views: 2027

Answers (1)

Alexandr Lazarev
Alexandr Lazarev

Reputation: 12882

I think that it is better to bind ajax request to reader.onload handler.

var file = document.getElementById('upload');
if(file.files.length > 0) {
    var reader = new FileReader();
    reader.onload = function(e) {
        settings.data += '&file=' + btoa(e.target.result);
        $.ajax({
            //send ajax ...
        });
    }
    reader.readAsText();
}

Or you could cancel your current ajax by returning false in beforeSend and create a new one in reader.onload.

$.ajaxSetup({
    beforeSend: function(xhr, settings) {
        var file = document.getElementById('upload');
        if(file.files.length > 0) {
            var reader = new FileReader();
            reader.onload = function(e) {
                settings.data += '&file=' + btoa(e.target.result);
                $.ajax(settings); // Send another ajax...
            }
            reader.readAsText();
        }
    }
});

Upvotes: 2

Related Questions