0

I got a Jquery function that read a FilesList and display in an IMG html object the image.

function load_images(files) {
    for (var i = 0; i < files.length; i++) {
        // Validate the image type
        if(validate_file(files[i])) {
            var reader = new FileReader();
            reader.onload = function(e) {    
                $(".upload_thumbnails").append(render_thumb(e.target.result, i)); // Return a string with the img object
            };
        } 
        reader.readAsDataURL(f);
    } 
}

But my images are not append in the sequential order of the fileList. The fileList (var files) is implement by an multiple input file html object.

Do you have any idea ?

Ludovic
  • 1,992
  • 1
  • 21
  • 44

1 Answers1

1

The method readAsDataURL is asynchronous meaning that your loop will create a lot of requests to load data, but because the method is asynchronous there is not way to to know in which order the onload callback will be called. The behaviour is non-deterministic.

This could be solved by storing all the elements in an array along with their index and then actually rendering out all the images when they have all loaded completely.

Another alternative is creating a placeholder div when the requests is started and capture it in the closure of the onload callback. Then you could append the image to that div, this would cause the behaviour you want.

Like this:

function load_images(files) {
    for (var i = 0; i < files.length; i++) {
        // Validate the image type
        if(validate_file(files[i])) {
            var reader = new FileReader(),
                div    = $("<div></div>");
            $(".upload_thumbnails").append(div);            

            reader.onload = function(e) {    
                div.append(render_thumb(e.target.result, i)); // Return a string with the img object
            };
        } 
        reader.readAsDataURL(f);
    } 
}
Hugo Tunius
  • 2,869
  • 24
  • 32
  • I understand my mistake but with you solution the problem is the same no ? It will just create many empty div and a final div with all image in it. – Ludovic Nov 04 '13 at 23:16
  • 1
    Really? I fail to see how that could happen, it should work just as you wanted. Could you post a jsFiddle? – Hugo Tunius Nov 05 '13 at 07:21
  • So it works as intended now? If so please mark the questions as answered. – Hugo Tunius Nov 10 '13 at 13:20
  • Nope look the HTML code when you load images, you have 3 empty div then a div with all images into it. The order is not the right one. – Ludovic Nov 10 '13 at 13:22
  • 1
    Oh yes ovbiously. The variable is getting hoisted. You'll need to create scope with a function. Like this, http://jsfiddle.net/u3d99/3/ This doesn't really feel optimal, but it works. For example you could use the array forEach method instead of a for loop. That would be nicer. – Hugo Tunius Nov 10 '13 at 13:25
  • Perfect, thank you so much ! I will change my for to a forEach. – Ludovic Nov 10 '13 at 13:42