Abe Miessler
Abe Miessler

Reputation: 85056

Reading files too quickly in javascript?

I have the following code:

oFReader = new FileReader(), rFilter = /^(?:image\/bmp|image\/cis\-cod|image\/gif|image\/ief|image\/jpeg|image\/jpeg|image\/jpeg|image\/pipeg|image\/png|image\/svg\+xml|image\/tiff|image\/x\-cmu\-raster|image\/x\-cmx|image\/x\-icon|image\/x\-portable\-anymap|image\/x\-portable\-bitmap|image\/x\-portable\-graymap|image\/x\-portable\-pixmap|image\/x\-rgb|image\/x\-xbitmap|image\/x\-xpixmap|image\/x\-xwindowdump)$/i;
oFReader.onload = function (oFREvent) {
    $("#preview").append("<img src='" + oFREvent.target.result + "' />");
};

function loadImageFile() {
    if (document.getElementById("uploadImage").files.length === 0) { return; }

    $.each(document.getElementById("uploadImage").files, function (index, value) {
        if (!rFilter.test(value.type)) { alert("You must select a valid image file!"); return; }
        oFReader.readAsDataURL(value);
    });
}

It is intended to take a collection of images that have been dragged onto a input of type file, and then preview those images in a div. My issue is that when I run this, only the last image appears. If I add a break point into my javascript and step through the code, both images are displayed.

I am assuming that this is happening because oFReader.onload is being called twice very quickly. I had considered using setTimeout or possibly declaring oFReader inside of my loop to try to avoid the conflict, but I'm wondering if there is a more elegant solution?

Upvotes: 2

Views: 357

Answers (1)

jfriend00
jfriend00

Reputation: 707318

You need a separate FileReader object for each file you are reading.

.readDataAsURL() is an asynchronous method. It finishes some time later after you call it. In your .each() loop, you are trying to read a new file before the previous one is done, thus stopping it before it completes.

You could do something like this:

function loadImageFile() {
    if (document.getElementById("uploadImage").files.length === 0) { return; }

    $.each(document.getElementById("uploadImage").files, function (index, value) {
        var oFReader = new FileReader(), rFilter = /^(?:image\/bmp|image\/cis\-cod|image\/gif|image\/ief|image\/jpeg|image\/jpeg|image\/jpeg|image\/pipeg|image\/png|image\/svg\+xml|image\/tiff|image\/x\-cmu\-raster|image\/x\-cmx|image\/x\-icon|image\/x\-portable\-anymap|image\/x\-portable\-bitmap|image\/x\-portable\-graymap|image\/x\-portable\-pixmap|image\/x\-rgb|image\/x\-xbitmap|image\/x\-xpixmap|image\/x\-xwindowdump)$/i;

        if (!rFilter.test(value.type)) { alert("You must select a valid image file!"); return; }
        oFReader.onload = function (oFREvent) {
            $("#preview").append("<img src='" + oFREvent.target.result + "' />");
        };
        oFReader.readAsDataURL(value);
    });
}

Upvotes: 3

Related Questions