0

First post on SO, but in fact a longtime user since I've found everything I need here… until now.

I'm facing a tricky problem with XHR. I may say that I'm kind of a newbie in JS, but I didn't expect this kind of thing and I can't get around…

So the thing is that I'm retrieving a bunch of images on a distant server with a "for" loop. No problem with that, it works. But I want to give them an id to use them with their "number" after, so that I can use them in a canvas, and animate it. I don't know where is the problem but the incrementation of the id goes wrong. Here is my code :

<body>

<button onclick="loadCanvas(113);">Click here</button>
<canvas id="targetedCanvas" width="768" height="512"></canvas>
<script>
    window.URL = window.URL || window.webkitURL;        

    function loadImages() {
        for (id = 0; id < 114; id++) {
            var url = 'http://myurl.com/IMG_'+id+'.JPG';
            var request = new XMLHttpRequest();
            request.open('GET', url, true);
            request.responseType = 'blob';
            request.onload = function(e) {
                if(this.status == 200) {
                    var blob = this.response;

                    var img = document.createElement('img');
                    img.id = id;
                    img.onload = function(e) {
                        window.URL.revokeObjectURL(img.src);
                    };
                    img.src = window.URL.createObjectURL(blob);
                    img.width = 0;
                    img.height = 0;
                    document.body.appendChild(img);
                    }
                }
            request.send(null);
            };
    }

    function loadCanvas(id) {
        var canvas = document.getElementById('targetedCanvas');
        var context = canvas.getContext('2d');
        var img = document.getElementById(id);
        context.drawImage(img,0,0);
    };

    loadImages();

</script>
</body>

So you see there is a button, when you click on it, it loads the image to the canvas to display it. When I want to display the id (console.log(id);), the id is ok out of the request.onload function (I mean, it goes like 1, 2, 3…) but inside the function it is always 113. This is the thing I can't understand. I guess this is because XHR is asynchronous, or something like that… This is where I am a real newbie…

Then if anyone has a key, or knows something to get around and use the XHR-loaded images in another way, I'd be glad to read it ! :)

Thank you very much SO community !

Adk3rn
  • 1
  • 1

1 Answers1

0

You need to use an self invoking function and pass the id in that function.

Because the requests are async in nature so till the time you will get even a single response the for loop will complete and the id will shoot to 114 and all the alloted id will (may) be 114. So preserve it with self invoking function.

 function loadImages() {
        for (id = 0; id < 114; id++) {
            (function(id){
            var url = 'http://myurl.com/IMG_'+id+'.JPG';
            var request = new XMLHttpRequest();
            request.open('GET', url, true);
            request.responseType = 'blob';
            request.onload = function(e) {
                if(this.status == 200) {
                    var blob = this.response;

                    var img = document.createElement('img');
                    img.id = id;
                    img.onload = function(e) {
                        window.URL.revokeObjectURL(img.src);
                    };
                    img.src = window.URL.createObjectURL(blob);
                    img.width = 0;
                    img.height = 0;
                    document.body.appendChild(img);
                    }
                }
            request.send(null);
            })(id);
            };
    }
void
  • 36,090
  • 8
  • 62
  • 107
  • This is an overly complicated way to do it, and relies on defining 113 instances of what is essentially the same callback method. It would be much easier and more efficient to assign an id property to each XHR object and read it in the callback. – Touffy Feb 21 '15 at 18:39
  • Thank you very much to both of you guys :-) I finally took @Touffy's solution. It was in fact not that hard but I didn't think about it. – Adk3rn Feb 21 '15 at 23:55