Search code examples
drop-down-menuvuejs2vue-componentselect-options

Vuejs2: Issue creating a reusable method to get options text in multiple HTML select lists


Vuejs2 (or any version) noob here. I have several inputs and selects dropdown lists (ddl) containing different data that I want to get the text values from to pass with my form. I don't want to write a method for each select ddl to get the text of each option. I've tried the code below, but I'm getting an error if I try to use the one method for both ddl:

"Cannot read property 'map' of undefined
    at VueComponent.getText" 

Please tell me what I'm doing wrong.

HTML:

<div class="food">
     <input type="text" 
            name="txt_myFood" 
            v-model="txt_myFood">

     <select id="sel_food" 
             v-model="sel_food" 
             v-on:change="getText(myFood, sel_food)">
         <option v-for="food in myFood" 
                 v-bind:value="food.value">{{ food.text }} 
         </option>
     </select>
</div>


<div class="colors">
     <input type="text" 
            name="txt_myColor" 
            v-model="txt_myColor"">

     <select id="sel_colors" 
             v-model="sel_colors" 
             v-on:change="getText(myColors, sel_colors)">
         <option v-for="color in myColors" 
                 v-bind:value="color.value">{{ color.text }} 
         </option>
     </select>
</div>

Vue

export default {
  data() {
    return {

      optionText: "",      
      sel_food: "",
      myFood: [
        { value: 0, text: "tuna" },
        { value: 1, text: "chicken" },
        { value: 2, text: "lamb" }
      ],

      sel_colors: "",
      myColors: [
        { value: 0, text: "red" },
        { value: 1, text: "blue" },
        { value: 2, text: "yellow" }
      ]
    };
  },
  methods: {
    getText(myArr=[], vModel="") {          

      var values = this.myArr.map(function(o) {
        return o.value;
      });
      var index = values.indexOf(this.vModel);
      this.optionText = this.myArr[index].text;
      console.log(this.optionText);
    }
  }
};

Thanks.

FiddleLink


Solution

  • Your problem is calling this on method argument.

    See this example from your code:

    ...
    
    getText(myArr=[], vModel="") {          
    var values = this.myArr.map(function(o) {
    ...
    

    Using this.myArr will make vue think you are trying to access the myArr in your data object. Since you don't have that in your object, you get errors like annot read property 'map' of undefined

    So, don't call this on method arguments. Just use myArr.map

    Here is your mode updated: http://jsfiddle.net/wpsoud1q/15/