-1

I am getting the following error : TypeError: slides[i] is undefined.

Its strange because shouldn't it be able to access the slides variable?

<script>
    $('document').ready(function() {
        $.ajax({
            type: "POST",
            url: "getSlides.php",
            data: '',
            cache: false,
            success: function(response)
            {
                var slides = JSON.parse(response);
                for (var i = 0; i < slides.length; i++) {
                    setTimeout(function() {
                        if (slides[i].type === 'image') {
                            $('#slideshow').html('<img src="' + slides[i].image_video + '" />');
                        }
                    }, 2000);
                }
            }
        });
    });
</script>
Vrutin Rathod
  • 900
  • 1
  • 12
  • 16

5 Answers5

1

It looks like the classic closure in a loop problem

$('document').ready(function () {
    $.ajax({
        type: "POST",
        url: "getSlides.php",
        dataType: 'json',
        cache: false,
        success: function (response) {
            $.each(slides, function (slide) {
                if (slide.type === 'image') {
                    $('#slideshow').html('<img src="' + slide.image_video + '" />');
                }
            })
        }
    });
});
Arun P Johny
  • 384,651
  • 66
  • 527
  • 531
1

You could proxy your sildes[i] to setTimeout function callback, ref, fiddle example

$('document').ready(function () {
    $.ajax({
        type: "POST",
        url: "getSlides.php",
        data: '',
        cache: false,
        success: function (response) {
            var slides = JSON.parse(response);
            for (var i = 0; i < slides.length; i++) {
                setTimeout(function (slide) {
                    if (slide.type === 'image') {
                        $('#slideshow').html('<img src="' + slide.image_video + '" />');
                    }
                }, 2000, slides[i]);
            }
        }
    });
});
krasu
  • 2,037
  • 23
  • 22
0

If I am not mistaking, this is a classic error, the setTimeout will execute async, after the loop has finished, so i should be equal to slides.length when the callback runs. To fix this, create a local scope for i, like this:

                for (var i = 0; i < slides.length; i++) {
                    (function(i){
                      setTimeout(function(callback) {
                        if (slides[i].type === 'image') {
                            $('#slideshow').html('<img src="' + slides[i].image_video + '" />');
                        }
                      }, 2000);
                    })(i)
                }
pax162
  • 4,735
  • 2
  • 22
  • 28
0

because due to setTimeOut it calls your code after 2000ms, on that time value of i is slides.length for which it throw the error.

You have to arrange for a distinct copy of "i" to be present for each of the timeout functions.

 success: function (response) {
     var slides = JSON.parse(response);
     for (var i = 0; i < slides.length; i++) {
         doSetTimeout(slides, i);

     }
 }

 function doSetTimeout(slides, i) {
     setTimeout(function () {
         if (slides[i].type === 'image') {
             $('#slideshow').html('<img src="' + slides[i].image_video + '" />');
         }
     }, 2000);
 }
Zaheer Ahmed
  • 28,160
  • 11
  • 74
  • 110
0

Try replace:

for (var i = 0; i < slides.length; i++) {

to:

for (var i  in slides) {
Dmitry Seleznev
  • 955
  • 7
  • 7
  • What is the difference? If `slides` is an array, simple `for` loop *must* be used. – VisioN Nov 14 '13 at 11:43
  • Do you sure that slides is array, not object? – Dmitry Seleznev Nov 14 '13 at 11:46
  • [I am not](http://stackoverflow.com/questions/19976568/typeerror-variable-is-undefined#comment29737428_19976568). However accidentally having an object with `length` property is rather doubtful. – VisioN Nov 14 '13 at 11:49