Skip to content Skip to sidebar Skip to footer

Clarification Required On Javascript In HTML5 FileAPI For Image Preview

I was looking at the new HTML5 file API for showing a preview of an image to be uploaded. I googled for some code and almost every example had the same structure, almost the same

Solution 1:

Sure.
The function-wrapped function, here serves the specific purpose of remembering which file it was you were looking at.

This might be less of a problem using your exact codebase, but if you had a multiple-upload widget, and you wanted to display a row of previews:

var my_files = [].slice.call(file_input.files),

    file, reader,

    i = 0, l = my_files.length;


for (; i < l; i += 1) {
    file = my_files[i];
    reader = new FileReader();

    // always put the handler first (upside down), because this is async
    // if written normally and the operation finishes first (ie:cached response)
    // then handler never gets called
    reader.onload = function (e) {
        var blob_url = e.target.result,
            img = new Image();

        img.src = blob_url;
        document.body.appendChild(img);
    };
    reader.readAsDataUrl(file);
}

That should all work fine. ...except... And it's clean and readable.

The issue that was being resolved is simply this:

We're dealing with async-handlers, which means that the value of file isn't necessarily the same when the callback fires, as it was before...

There are a number of ways to potentially solve that.
Pretty much all of them that don't generate random ids/sequence-numbers/time-based hashes to check against on return, rely on closure.

And why would I want to create a whole management-system, when I could wrap it in a function and be done?

var save_file_reference_and_return_new_handler = function (given_file) {
    return function (e) {
        var blob_url  = e.target.result,
            file_name = given_file.name;

        //...
    };
};

So if you had that at the top of the function (above the loop), you could say:

reader = new FileReader();
reader.onload = save_file_reference_and_return_new_handler(file);
reader.readAsDataUrl(file);

And now it will work just fine.

Of course, JS people don't always feel compelled to write named functions, just to store one item in closure to remember later...

reader.onload = (function (current_file) {
    return function (e) {
        var blob_url  = e.target.result,
            file_name = current_file.name;
    };
}(file));

Post a Comment for "Clarification Required On Javascript In HTML5 FileAPI For Image Preview"