Search code examples
formsvuejs2radio-buttonbootstrap-vueselectinput

VUEJS Set select default values according to api response property values (displays undefined)


I have a user card list that displays some properties of the user (obtained with axios api call). On click edit button, an edit page is opened and those same list items are passed to this new page, but now become text inputs, radio buttons or select, depending on the data. I would like to display the data passed from the previous page as default in the inputs, and then the user can edit them if needed. The text inputs display the data (the ones coming from the api response) correctly, but I also need the radio button to be checked, if the value is true (not checked if false), and the select input to display as default value the original data. Here the code for the radio buttons (I am using vue-bootstrap):

<b-form-radio v-model="profileData.if_bike_owned" value="Y" >
YES
</b-form-radio>
<b-form-radio v-model="profileData.if_bike_owned" value="N">
NO
</b-form-radio>
<b-form-radio v-model="profileData.if_motorcycle_owned" value="Y">
YES
</b-form-radio>
<b-form-radio v-model="profileData.if_motorcycle_owned" value="N">
NO
</b-form-radio>

And here the select:

<label v-if="profileData.if_motorcycle_owned"  for="select-info-moto">
   Engine:
</label>
 <b-form-select
   name="select-info-moto"
   v-if="profileData.if_motorcycle_owned"
   v-model="profileData.user_motorcycle_characteristic"
   :options="[
      {
         value: null,
         text: 'Choose'
      },
      '50cc',
      '225cc - 250cc',
      '250cc - 500',
      'More than 500cc'
   ]"
/>
<label v-if="profileData.if_cars_owned" for="select-car-power">
Car power
</label>
<b-form-select
  name="select-car-power"
  v-if="profileData.if_cars_owned"     
  v-model="profileData.user_car_powered_by"
  :options="[
   {
      value: null,
     text: 'Choose'
   },
   'Benzina',
   'Diesel',
    'GPL',
   'Hybrid'
 ]" />

I am not using any v-for, inputs are just placed inside a <b-form>. The object profileData which I am getting these properties from, has basic structure, like:

profileData: {…}
  home_address_string: ('Street 1')
  id: (3)
  if_bike_owned: (true)
  if_cars_owned: (true)
  if_motorcycle_owned: (false)
  user_car_powered_by: ('Hybrid')
  user_car_type: ('City car')
  user_motorcycle_characteristic: (250)

Can someone point me how to deal with it? Or direct me to some online resources I might be missing? I'm looking for something similar the all day, but in vuejs I can't find much similar to what I need, and I am not very much experienced programmer...

Thank you very much x

UPDATE I got rid of the checkboxes, I am using only select (even for yes or no, they can be selected). Now all of them have this structure:

<b-form-select
 name="select-modello-auto"
 type="select"
 v-if="profileData.if_cars_owned"   
 v-model="profileData.user_car_type"
 :options="[
   {
    value: profileData.user_car_type,
    select: profileData.user_car_type
   },
   'City car',
   'Stationwagon',
   'SUV',
   'Van'
 ]"
/> 

In another page, in this same app, this part:

{
  value: profileData.user_car_type,
  select: profileData.user_car_type
}

does its job, correctly rendering the property got from the api response by default. I read that the select value must be equal to one of the options, so for example I changed the select for sex in true and false, but it doesn't work.


Solution

  • At the end, it wasn't that difficult. A piece of code that explained how I achieved that:

    <label for="select-if-car">Owns a car?</label>
      <b-form-select
        name="select-if-car"
        type="select"
        v-model="profileData.if_cars_owned"
        :options="boolean"
        required
      />
    <label
      v-if="profileData.if_cars_owned"
      for="select-car-type"
    >
    Select car type
    </label>
    <b-form-select
      name="select-car-type"
      type="select"
      v-if="profileData.if_cars_owned"   
      v-model="profileData.user_car_type"
      :options="carTypes"
      required
    />
    

    In the script:

    data(){
      return {
        carTypes: [
            {
              value: null, text: 'Choose an option'
            },
            {
              text:'City car', value: 'CITY_CAR'
            },
            {
              text:'Station wagon', value: 'STATION_WAGON'
            },
            {
              text:'Berlina sportiva', value: 'BERLINA_SPORTIVA'
            },
            {
              text:'Compatta', value: 'COMPATTA'
            },
            {
              text:'SUV', value: 'SUV'
            },
            {
              text:'Van', value: 'VAN'
            }
          ],
          boolean: [
            {
              value: null, text: 'Choose an option'
            },
            {
              text: 'Yes', value: 'true'
            },
            {
              text: 'No', value: 'false'
            }      
          ],
       }
    }
    

    With v-model="profileData.user_car_type" I am binding the value gotten by the api (in my case the object is called profileData and the property I want to access is user_car_type).

    Worth to notice, I used the syntax

    {
      text:'Van', value: 'VAN'
    }
    

    because for the select to work, the value must be exactly the same as the one coming from the api request, and the text is the one we actually see in the UI. Also, it's better to supply

    {
     value: null, text: 'Choose an option'
    },
    

    in case the user option is not among the options provided, otherwise the first option will be passed by default. Hope to help someone. Thanks, x