McTschecker
McTschecker

Reputation: 35

Element Ui component is not rerendering on vue component prop change

I have a parent component and multiple child components, which use the same prop. This prop is an array of keys for a dropdown menu in element.js. When the children render the first time, they contain no data. However, once the keys from arrive using vuefire the children get the dropdown menu items. However, the element dropdown menu is not rerendered as it should have been. However using the vue dev tools, I can see that the dropdown menu entries have been passed down as a key. When vue does a hot reload, because of a file change, the keys will load. Once the entries are loaded, I can select the entry and everything works as expected.

I also had the same results using the vuetify dropdown and the HTML dropdown. Both have the same issue.

parent

<template>
  <div class="setup">
    <h1>Setup</h1>
    <div class="selectIngredients" v-for="number in 6">
      <setupSelection :bottle="number" :ingredients="options" />
    </div>
  </div>
</template>

<script>
import {db} from "@/firebaseConfig"
import setupSelection from '@/components/setupSelection';
export default {
  components: {
    setupSelection,
  },
  firestore: {
    options: db.collection('ingredients'),
  },
};
</script>

child

<template>
  <div class="ingredientSelector">
    <h3>Select for Pump <span>{{bottle}}</span></h3>
    <el-select v-model="selected" clearable placeholder="Select" >
      <el-option
        v-for="ingredient in ingredients"
        v-bind:key="ingredient.text"
        v-bind:label="ingredient.text"
        v-bind:value="ingredient">
      </el-option>
    </el-select>
     <!-- <v-select
        v-model="selected"
        :items="ingredients"
        label="Select a favorite activity or create a new one"
      ></v-select> -->
    <!-- <select v-model="selected" v-for="ingredient in ingredients">
      <option :value="ingredient.value">{{ingredient.text}}</option>
    </select> -->
  </div>
</template>

<script>
import {db} from "@/firebaseConfig";
export default {
  props: {
    ingredients: { required: true },
    bottle: { type: Number, required: true },
  },
  data() {
    return {
      selected: ''
    }
  },
  },
};
</script>

I expected the dropdown menu to update once the client received them.

Thank you!

Upvotes: 0

Views: 1378

Answers (2)

skirtle
skirtle

Reputation: 29112

I haven't used Vuefire myself but I read the following in the documentation:

Make sure to create any property added to firestore in data as well

https://github.com/vuejs/vuefire/tree/master/packages/vuefire#firestore-option

Similar advice is given here:

https://vuefire.vuejs.org/vuefire/binding-subscriptions.html#declarative-binding

In your example you don't have options in the parent's data. This would, presumably, leave it non-reactive, leading to the symptoms you describe.

Upvotes: 1

Steven Spungin
Steven Spungin

Reputation: 29139

Use a data property for your items, and set them after the options are loaded.

data() {
    return {
      options: []
    }
  },
created() {
   db.collection('ingredients').then(data=> this.options = data}
}

The promise returned from db.collection('ingredients') is not reactive.

Even better approach would be to set options: null, and show a loading indicator until it is an array.

Upvotes: 0

Related Questions