1

I am having a bit of a problem getting an array length in vue. The array is in the data object as

data() {
    return {
      slides: [
        {
          image: require("@/assets/img/carousel/couple.jpg"),
          caption:
            "A couple wearing masks kiss in a shopping area in downtown Shanghai, China, on February 16, 2020."
        },
        {
          image: require("@/assets/img/carousel/dogs.jpg"),
          caption:
            "Dogs wearing masks are seen in a shopping area in downtown Shanghai on February 16, 2020."
        },
         etc... ]

and then in methods

methods: {
    playSlides() {
      this.imgSource = this.slides[this.currentSlide].image;
      this.figCaption = this.slides[this.currentSlide].caption;
      let slideInterval = setInterval(nextSlide, 2000);

      function nextSlide() {
        console.log(`slides.length is: ${this.slides.length}`);
        this.currentSlide = (this.currentSlide + 1) % this.slides.length; // % is same as mod operator
        console.log(Array.isArray(this.slides));
      }
    }
  }
};

I know its been a long day but this.slides.length is undefined?? and Array.isArray(this.slides) is false. Any body see what is the problem most appreciated...

3
  • 1
    const nextSlide = () => {...} to bind this. Commented Apr 4, 2020 at 0:34
  • Sorry. still getting undefined. Commented Apr 4, 2020 at 0:39
  • You probably got undefined because you declared the variable nextSlide below where you used it. Commented Apr 4, 2020 at 0:53

1 Answer 1

1

When you use function name(), the this context is not the this context of the parent object, it is in fact the this context of window.

In order to make this equal to the vue instance, you have to use an arrow function, or use the .bind prototype to explicitly bind what you want this to be in your function.

new Vue({
  data() {
    return {
      currentSlide: 1,
      slides: [{
          image: "@/assets/img/carousel/couple.jpg",
          caption: "A couple wearing masks kiss in a shopping area in downtown Shanghai, China, on February 16, 2020."
        },
        {
          image: "@/assets/img/carousel/dogs.jpg",
          caption: "Dogs wearing masks are seen in a shopping area in downtown Shanghai on February 16, 2020."
        }
      ]
    };
  },

  created() {
    this.playSlides();
    this.playSlides2();
  },

  methods: {
    playSlides() {
      this.imgSource = this.slides[this.currentSlide].image;
      this.figCaption = this.slides[this.currentSlide].caption;
      let slideInterval = setInterval(nextSlide.bind(this), 2000);

      function nextSlide() {
        console.log(`slides.length is: ${this.slides.length}`);
        this.currentSlide = (this.currentSlide + 1) % this.slides.length; // % is same as mod operator
        console.log(Array.isArray(this.slides));
      }
    },

    playSlides2() {
      this.imgSource = this.slides[this.currentSlide].image;
      this.figCaption = this.slides[this.currentSlide].caption;

      const nextSlide = () => {
        console.log(`slides.length is: ${this.slides.length}`);
        this.currentSlide = (this.currentSlide + 1) % this.slides.length; // % is same as mod operator
        console.log(Array.isArray(this.slides));
      }

      let slideInterval = setInterval(nextSlide, 2000);
    }
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.min.js"></script>

Sign up to request clarification or add additional context in comments.

2 Comments

Mucho appreciado. I changed this line to let slideInterval = setInterval(nextSlide.bind(this), 2000); and now all is working. Everyone stay safe.
Oh yes! my bad. Edited the answer. I was running the function directly to debug, and I forgot that setinterval is taking a function as callback. Good spot!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.