Search code examples
vue.jsv-forv-model

Vue v-model/v-for doesn't update on mount, but after first manual change


I have a dropdown list "functions" that is filled with database entries and a dropdown list with 2 hardcoded entries. When the vue website is opened the dropdown list remains empty but as soon as I change the value of the other dropdown field the desired data from the database is available.

I'm a bit confused because I expected that adding "retrieveFunctions()" into the mounted() function would trigger the v-for, and even more confused that changing something in another select field suddenly triggers it.

The HTML code:

<template>
<div class="submit-form">
    <div v-if="!submitted">
        <div class="row">
            <div class="col-sm-12">
                <p><a style="width:500px" class="btn btn-info" data-toggle="collapse" href="#generalInformation" role="button" aria-expanded="true" >
                    General Information</a></p>
            <div class="collaps show" id="generalInformation">
            <!-- NAME -->          
            <div class="form-group">
                <input placeholder="Name" type="text" class="form-control"
                id="name" required v-model="component.name" name="name">
            </div>   
            <!-- DOMAIN -->          
            <div class="input-group mb-3">
                <div class="input-group-prepend">
                <label style="width:100px" class="input-group-text" for="inputGroupDomain">Domain</label>
                </div>
                <select v-model="component.domain" 
                        class="custom-select" 
                        id="inputGroupDomain"
                >
                    <option value="Power System">Power System</option>
                    <option value="ICT">ICT</option>
                </select>
            </div>
            <!-- FUNCTION -->
            <div class="input-group mb-3">
                <div class="input-group-prepend">
                <label style="width:100px" class="input-group-text" for="inputGroupFunction">Functions</label>
                </div>
                <select v-model="_function" class="custom-select" id="inputGroupFunction">
                        <option :class="{ active: index == currentIndex }"
                            v-for="(_function, index) in functions"
                            :key="index"
                            value= _function.name>
                        {{ _function.name }}
                    </option>              
                </select>
      </div>
    </div>
    <p>
    <button @click="saveComponent" class="btn btn-success">Add Component</button>
    </p>
    </div>
    </div>    
    </div>
<div v-else>
    <h4>Component was added succesfully!</h4>
    <button class="btn btn-success" @click="newComponent">Proceed</button>
</div>

The script part:

<script>
import FunctionDataService from "../services/FunctionDataService";
export default {
  name: "add-component",
  data() {
    return {
      component: {
        id: null,
        name: "",
        type: "",
        domain: "",
      },
      submitted: false
    };
  },
    methods: {
        retrieveFunctions() {
        FunctionDataService.getAll()
        .then(response => {
            this.functions = response.data;
            console.log(response.data);
            })
            .catch(e => {
            console.log(e);
            });
        },
        refreshList() {
        this.retrieveFunctions();
        },
    },
    mounted() {
        this.retrieveFunctions();
    }
};
</script>
        refreshList() {
        this.retrieveFunctions();
        },
    },
    mounted() {
        this.retrieveFunctions();
    }
};
</script>

State in the beginning: Dropdown list empty

State in the beginning

State after selecting something in the upper dropdown list: Database entries are visible and correct

State after selecting something in the upper dropdown list


Solution

  • You need to initiate all responsive properties on the data return object with either a value (empty string, array, object, etc) or null. Currently it's missing the _function attribute used in the select v-model and the functions array used in the v-for. You can try to change the data to the following:

    data() {
        return {
          _function: "",
          functions: [],
          component: {
            id: null,
            name: "",
            type: "",
            domain: "",
          },
          submitted: false
        };
      },