Home > Net >  Default props value are not selected in vue3 options api
Default props value are not selected in vue3 options api

Time:03-02

I created a select2 wrapper in vue3 with options API everything working fine but the problem is that when getting values from calling API it's not selected the default value in the select2 option. but when I created a static array of objects it does. I don't know why it's working when it comes from the API

Parent Component

Here you can I passed the static options array in options props and my selected value is 2 and it's selected in my Select2 component, but when passed formattedCompanies it's not which is the same format as the static options array then why is not selected any reason here..?

<template>
  <Form @submitted="store()" :processing="submitting">
     <div >
        <div >
           <div >
              <label>Company Name</label>

              <Select2
                :options="options"
                v-model="selected"
                placeholder="Select Company"
              />

              <ValidationError :errors="errors" error-key="name" />
           </div>
        </div>
     </div>
  </Form>
</template>


<script>
import Form from "@/components/Common/Form";
import Select2 from "@/components/Common/Select2";

export default {
    components: {
        Select2,
        Form
    },

    data() {
        return {
            selected : 2,

            companies : [],

            options: [ // static array

                { id: 1, text: 'hello' },
                { id: 2, text: 'hello2' },
                { id: 3, text: 'hello3' },
                { id: 4, text: 'hello4' },
                { id: 5, text: 'hello5' },
            ],
        }
    },

    mounted() {
        this.getAllMedicineCompanies()
    },

    computed:{
        formattedCompanies() {
            let arr = [];
            this.companies.forEach(item => {
                arr.push({id: item.id, text: item.name})
            });

            return arr;
        }
    },

    methods: {
        getAllMedicineCompanies(){
            axios.get('/api/get-data?provider=companies')
                .then(({ data }) => {
                    this.companies = data
                })
        },
    }
}
</script>

Select2 Component

Here is what my select2 component look like, did I do anything wrong here, please anybody help me

<template>
    <select >
        <slot/>
    </select>
</template>

<script>
export default {
    name: "Select2",

    props: {
        options: {
            type: [Array, Object],
            required: true
        },

        modelValue: [String, Number],

        placeholder: {
            type: String,
            default: "Search"
        },

        allowClear: {
            type: Boolean,
            default: true
        },
    },

    mounted() {
        const vm = this;

        $(this.$el)
            .select2({ // init select2
                data: this.options,
                placeholder: this.placeholder,
                allowClear: this.allowClear
            })
            .val(this.modelValue)
            .trigger("change")
            .on("change", function () { // emit event on change.
                vm.$emit("update:modelValue", this.value);
            });
    },

    watch: {
        modelValue(value) { // update value
            $(this.$el)
                .val(value)
                .trigger("change");
        },
        options(options) { // update options
            $(this.$el)
                .empty()
                .select2({data: options});
        },
    },

    destroyed() {
        $(this.$el)
            .off()
            .select2("destroy");
    }
}
</script>

CodePudding user response:

Probably when this Select2 mounted there is no companies. It is empty array after that it will make API call and it it populates options field and clear all options.

Make:

        companies : null,

Change it to

     <Select2
            v-if="formattedCompanies"
            :options="formattedCompanies"
            v-model="selected"
            placeholder="Select Company"
          />

It should be like this:

<template>
  <Form @submitted="store()" :processing="submitting">
     <div >
        <div >
           <div >
              <label>Company Name</label>


              <Select2
                  v-if="formattedCompanies"
                  :options="formattedCompanies"
                  v-model="selected"
                  placeholder="Select Company"
             />

              <ValidationError :errors="errors" error-key="name" />
           </div>
        </div>
     </div>
  </Form>
</template>


<script>
import Form from "@/components/Common/Form";
import Select2 from "@/components/Common/Select2";

export default {
    components: {
        Select2,
        Form
    },

    data() {
        return {
            selected : 2,

            companies : null,

            options: [ // static array

                { id: 1, text: 'hello' },
                { id: 2, text: 'hello2' },
                { id: 3, text: 'hello3' },
                { id: 4, text: 'hello4' },
                { id: 5, text: 'hello5' },
            ],
        }
    },

    mounted() {
        this.getAllMedicineCompanies()
    },

    computed:{
        formattedCompanies() {
            let arr = [];
            this.companies.forEach(item => {
                arr.push({id: item.id, text: item.name})
            });

            return arr;
        }
    },

    methods: {
        getAllMedicineCompanies(){
            axios.get('/api/get-data?provider=companies')
                .then(({ data }) => {
                    this.companies = data
                })
        },
    }
}
</script>

CodePudding user response:

The problem was that my parent component and Select2 component mounted at the same time that's why my computed value is not initialized so the selected value is not selected in the option,

problem solved by setTimeOut function in mounted like this

Select2 Component

<script>
mounted() {
  const vm = this;

   setTimeout(() => {
      $(this.$el)
      .select2({ // init select2
         data: this.options,
         placeholder: this.placeholder,
         allowClear: this.allowClear
      })
      .val(this.modelValue)
      .trigger("change")
      .on("change", function () { // emit event on change.
         vm.$emit("update:modelValue", this.value);
      });
   }, 500)
},
</script>
  • Related