-2

Hey guys I have a javascript file like this:

  // An object that holds all images and words.
var items = {
    "images": [
        {
            "imageLink": "elephant.png",
            "imageText": "Elephant"
        },
        {
            "imageLink": "rabbit.jpeg",
            "imageText": "Rabbit"
        },
        {
            "imageLink": "tiger.jpg",
            "imageText": "Tiger"
        },
        {
            "imageLink": "turtle.png",
            "imageText": "Turtle"
        }

    ]
};

// Hide the buttons from the screen

var hidebuttons = function() {
    document.getElementById("buttonWrapper").classList.add("hide");
};

var replaceTitle = function(title) {
    document.getElementById("header").firstElementChild.innerHTML = title;
}

var rotateImage = function() {
    console.log(items.images.length);
    for (i = 0; i < items.images.length; i++) {
        setInterval(function() {
          //  document.getElementById("imageToRotate").src= "img/" + items.images[i].imageLink;
            console.log(items.images);
            if (i === items.images.length -1) {
                i = 0;
            }
        }, 1000);

    }

}

and when I I use items.images it returns the follwoing in the console:

Array[4]
0:    Object
1:    Object
      imageLink: "rabbit.jpeg"
      imageText: "Rabbit"
     __proto__: Object

but whenerver I use

items.images[i] 
items.images.i

It always returns "undefined". Does anyone have an idea what I'm doing wrong? thanks for the help. Cheers!

Rodney Wormsbecher
  • 897
  • 2
  • 17
  • 39

5 Answers5

2

Because when the setTimeout callback runs, the value of i is already i === items.images.length. The reason is described here. See this simplified:

for (var i = 0; i < 3; i++) {
    setTimeout(() => {
        console.log(i);
    }, 100);
}

I assume you wanted something like a carousel, like this:

var i = 0;
setInterval(() => {
    console.log(i);
    i = (i + 1) % 3;
}, 1000);

Btw you use i as a global variable instead of a local one, and you start several interval timers for no reason.

Community
  • 1
  • 1
Tamas Hegedus
  • 28,755
  • 12
  • 63
  • 97
2

I think you want something like this:

var items = {
    "images": [
        {
            "imageLink": "elephant.png",
            "imageText": "Elephant"
        },
        {
            "imageLink": "rabbit.jpeg",
            "imageText": "Rabbit"
        },
        {
            "imageLink": "tiger.jpg",
            "imageText": "Tiger"
        },
        {
            "imageLink": "turtle.png",
            "imageText": "Turtle"
        }

    ]
};

var rotateImage = function() {
  var numberOfImages = items.images.length;
  var i =0;
        setInterval(function() {
          //runs every second;
          var image = items.images[i++];
          console.log(image); //your logic with image should be here
          if(i == numberOfImages){
            i = 0;
          }
        }, 1000);

    }
rotateImage();
xszaboj
  • 1,035
  • 7
  • 21
1

You ran into a pitfall: In JavaScript, variables are function-scoped. That means, your i has the value 4 when your setInterval gets fired (because the for loop is over then and will leave i at 4).

Or, what I think you try to do, you nested the code the wrong way so I rewrote it in the hope it does now, what you need:

var rotateImage = function() {
    var currentImageIndex = 0;

    setInterval(function() {
        console.log(items.images[currentImageIndex]); //do with it what you want.
        currentImageIndex++;
        if (currentImageIndex >= items.images.length) currentImageIndex = 0; //reached end. Reset counter
    }, 1000);
};

The function is a bit misnamed, if my guess is right, because it suggests that it performs only one cycle. It should be named startRotatingImages() or something like this.

0

Could it be this: for (i = 0; i < items.images.length; i++) {

You haven't initialised var i in the for loop, so i is still undefined :)

EDIT: Solved it. Slightly different reason, but same problem. i only becomes defined after after you run rotateImage() for the first time. When it does become defined, its value is quickly set to 4, which overshoots the array by one (there are four items, and i would access the fifth).

Jamie Birch
  • 5,839
  • 1
  • 46
  • 60
0

After some advice from @charlietfl I got rid of the for loop and manually coded a counter which solved the problem. See the code below for the details.

  var rotateImage = function() {
    var i = 0;
    var interval = window.setInterval(function () {
            i++;
            document.getElementById("imageToRotate").src= "img/" + items.images[i].imageLink;

            if (i === items.images.length -1) {
                i = 0;
            }
    }, 125);
};
Rodney Wormsbecher
  • 897
  • 2
  • 17
  • 39