1

I am learning Vue and I am trying to access a string in an array by it's index, but I always get an error when trying to read the string. Here's my code:

var vm = new Vue({
    el: '#top',
    data: {
        Cars: [],
        DefaultCarList: [],
        AddedCars: [],
        SelectedCar: ''
    },
    methods: {
        addCar: function(car) {
            var addedCarCount = this.AddedCars.length;
            var defaultCarCount = this.DefaultCarList.length;

            var containsCar = function () {
                for (var i = 0; i < addedCarCount; i++)
                {
                    if (this.AddedCars[i] === car) // error here
                    {
                       return true;
                    }
                }
                return false;
            }

            var carIsValid = function() {
                for(var i = 0; i < defaultCarCount; i++)
                {
                   if(this.DefaultCarList[i] === this.SelectedCar) // error here
                   {
                       return true;
                   }  
                }
                return false;
            }
            if (containsCar() === false && carIsValid){
                this.AddedCars.push(car);
            }
        }
    }
})

HTML:

<label for="carsId">Cars</label>
            <select id="carsId" name="cars" v-model="SelectedCar">
                <option disabled value="">Select</option>
                <option v-for="car in DefaultCarList" :value="flavor">{{car}}</option>
            </select>
            <div>
                <button type="button" class="hollow button success small"
                        v-on:click="addCar(SelectedCar)">Add Flavor</button>
            </div>

Is it valid to iterate over an array like this in Vue and access the property by it's index? What is the correct way to do this?

Mihai Alexandru-Ionut
  • 41,021
  • 10
  • 77
  • 103
user1206480
  • 1,606
  • 2
  • 25
  • 43

2 Answers2

2

Problem is with 'this' keyword it uses inner this where it doesn't have DefaultCarList variable, should use () => {} syntax .Error in this code

var carIsValid = function() {
            for(var i = 0; i < defaultCarCount; i++)
            {
               if(this.DefaultCarList[i] === this.SelectedCar) // error here
               {
                   return true;
               }  
            }
            return false;
        }

should be

var carIsValid = () => {
            for(var i = 0; i < defaultCarCount; i++)
            {
               if(this.DefaultCarList[i] === this.SelectedCar) // error here
               {
                   return true;
               }  
            }
            return false;
        }

and

var containsCar = () => {
            for (var i = 0; i < addedCarCount; i++)
            {
                if (this.AddedCars[i] === car) // error here
                {
                   return true;
                }
            }
            return false;
        }
alexKhymenko
  • 4,840
  • 17
  • 36
1

The problem is that this it's not a reference to your model.

In your example this is a reference to window object.

Have a look here in order to understand the scope of this keyword in javascript.

You should use arrow functions.

var containsCar = () => {
      for (var i = 0; i < addedCarCount; i++)
      {
        if (this.AddedCars[i] === car) // error here
        {
            return true;
        }
      }
      return false;
}

or you could just define a self variable.

var self=this;
var containsCar = function()  {
      for (var i = 0; i < addedCarCount; i++)
      {
        if (self.AddedCars[i] === car) // error here
        {
            return true;
        }
      }
      return false;
}

Further more, I recommand you to use native javascript functions in order to have a clean code.

var containsCar = function () {
      for (var i = 0; i < addedCarCount; i++)
      {
        if (this.AddedCars[i] === car) // error here
        {
            return true;
        }
      }
      return false;
}

var carIsValid = function() {
        for(var i = 0; i < defaultCarCount; i++)
        {
           if(this.DefaultCarList[i] === this.SelectedCar) // error here
           {
               return true;
           }  
        }
        return false;
 }

can be achieved using some method :

The some() method tests whether at-least one element in the array passes the test implemented by the provided function.

var containsCar = () => {
      return this.AddedCars.some(a=>a==car);
}
var carIsValid = () => {
      return this.DefaultCarList.some(a=>a === this.SelectedCar);
}
Mihai Alexandru-Ionut
  • 41,021
  • 10
  • 77
  • 103