Skip to content

Generate multiple select inputs with v-for

I am desperately trying to generate multiple select inputs for a given JSON from an Backend but I cant make it work. The JSON response I am getting looks smth like this:

{
    "selectData": [
        {
            "id": "ats_2323680",
            "label": "Follow up",
            "value": "option_id_1"
        },
        {
            "id": "ats_2323701",
            "label": "1st Interview, Client",
            "value": "option_id_1"
        },...
    ],
    "optionData": {
        "texts": [
            "Sourced",
            "On hold",
            ...
        ],
        "values": [
            "option_id_1",
            "option_id_2",
        ]
    }
}

Ive already tried several ways and my last attempt looks like this:

Template:

 <div v-for="select in selectData" :key="select.id">
          <p>{{ select.label }}</p>
          <v-select
            :items="optionData.texts"
            :value="getOptionById(select.value)"
            @input="(id) => updateSelect(select, id)"
          ></v-select>
  </div>

Script:

<script>
export default {
  data() {
    return {
      selectData: [],
      optionData: {
        values: [],
        texts: [],
      },
    };
  },
  methods: {
    fetchData() {
      const headers = this.authorizationHeader;
      axios
        .get(url,
          {
            headers,
          }
        )
        .then((response) => {
          let data = response.data;
          this.selectData = data.selectData;
          this.optionData = data.optionData;
        })
        .catch((error) => console.log(error));
    },
    updateSelect(select, id) {
      select.value = id;
    },
    getOptionById(id) {
      let i = this.optionData.values.findIndex((x) => x === id);
      return this.optionData.texts[i];
    },
  },
  mounted() {
    this.fetchData();
  },
};
</script>

I am also not super happy with the JSON struct I am getting. The reason that the optionTextId is also send is, that the optionTexts will be in different languages. I am really happy with any advise.

Answer

I think I solved it. I think it was a classy case of overthinking.

First I changed the JSON structure in the backend like:

{
    "selectData": [
        {
            "id": "ats_2323680",
            "label": "Follow up",
            "text": "Sourced",
        },
        {
            "id": "ats_2323701",
            "label": "1st Interview, Client",
            "text": "Kandidaten nachgefasst",
        },
        ...
    ],
    "optionData": {
        "texts": [
            "Sourced",
            "Kandidaten kontaktiert",
            ...
        ],
        "values": [
            "option_id_1",
            "option_id_2",
            ...
       ]
    }
}

Then I changed the Vue code to: Template:

<div v-for="select in selectData" :key="select.id">
            <label for="location">{{ select.label }}</label>
            <select id="location" name="location" v-model="select.text">
              <option
                v-for="option in optionData.texts"
                :key="option"
                :value="option"
              >
                {{ option }}
              </option>
            </select>
</div>

Script:

<script>
export default {
  data() {
    return {
      selectData: [],
      optionData: {
        values: [],
        texts: [],
      },
    };
  },
  methods: {
    fetchData() {
      const headers = this.authorizationHeader;
      axios
        .get(
          url,
          {
            headers,
          }
        )
        .then((response) => {
          let data = response.data;
          this.selectData = data.selectData;
          this.optionData = data.optionData;
        })
        .catch((error) => console.log(error));
    },
  },
  mounted() {
    this.fetchData();
  },
};
</script>

Apparently changing the JSON struc and using v-model did the magic. Might be obvious. Hope this helps a lost soul like me at some point 🙂