Search code examples
javascriptfirebasefirebase-realtime-databasevuejs2vuefire

Updating ref dynamically Vuejs and Vuefire


First of all, I am design student and I use vuejs for prototyping my senior project. So this is not real working project. Just prototype of some diary app.

Basicly my isuue is, I have a list component which render my firebase array. In firebase daily arrays called with a key which manually edited by me. And each key represent a day like 20180519, 20180520. And, there is a datepicker component which emits dates this format (YYYYMMDD) to firebase.js which is my firebase config file.

List component structure is like:

<template>
    <div id="list">
        <ul>
            <li v-show="current" v-for="(item, index) in list"></li>
            <li v-show="!current" v-for="(item, index) in prevList"></li>
        </ul>
    </div>
</template>

<script>
import { today, prevList } from '.././firebase';
export default {
  name: 'List',
  data() {
    return {
      current: true,
      list: [],
      prevList: [],
    }
  },
  mounted() {
    this.$root.$on('checkYesterday', data => {
        this.current = data
    });
  },
  firebase: {
    list: today,
    prevList: prevList
  },
};
</script>

My date picker component emits dates to firebase.js via an EventBus. It is like

<template>
    <datepicker v-on:selected="doSelection"><datepicker>
</template>
<script>
import moment from 'moment';
import Datepicker from 'vuejs-datepicker';
import { EventBus } from '.././firebase';
export default {
  name: 'Header',
  data() {
    return {
      date: moment().format('LL'),
      openDatePicker: false,
    };
  },
  methods: {
    doSelection(val) {
      const pickerValue = moment(val).format('YYYYMMDD');
      const currentDay = moment().format('YYYYMMDD');
      EventBus.$emit('selectedDayEvent', pickerValue);
      if (pickerValue === currentDay) {
        this.$root.$emit('checkYesterday', true)
      } else {
        this.$root.$emit('checkYesterday', false)
      }
    }
  },
  components: {
    Datepicker,
  }
};
</script>

So, when user selects a day, EventBus emits date to firebase.js and also emit list component for which list rendered.

firebase.js file is like,

import { initializeApp } from 'firebase';
import moment from 'moment';
import Vue from 'vue';
export const EventBus = new Vue({
  data: {
    daySelected: '',
  }
});

const app = initializeApp({
  apiKey: "...",
  authDomain: "...",
  databaseURL: "...",
  projectId: "...",
  storageBucket: "",
  messagingSenderId: "..."
})

const day = moment().format('YYYYMMDD');
EventBus.$on('selectedDayEvent', pickerValue => {
  this.daySelected = pickerValue;
});


export const db = app.database();
export const today = db.ref(`${day}`);
export const prevList = db.ref(`${this.daySelected}`);

In firebase.js today executed properly but, prevList doesn't updated when date selected via datepicker. But daySelected variable updated when day changes via datepicker in EventBus.

How can I update prevList ?


Solution

  • According to document

    This function will get executed only once. If you want to have automatic rebind (pretty much like a computed property) use a $watch and call $unbind and then $bindAsArray

    You might want to store daySelected as a data property:

       <script>
        import { today, EventBus, db } from '.././firebase';
        export default {
          name: 'List',
          data() {
            return {
              current: true,
              list: [],
              prevList: [],
              daySelected: ''
            }
          },
          created() {
            this.$bindAsArray('prevList', db.ref(`${this.daySelected}`))
          },
          mounted() {
            this.$root.$on('checkYesterday', data => {
                this.current = data
            });
            EventBus.$on('selectedDayEvent', pickerValue => {
             this.daySelected = pickerValue;
            });
          },
          watch: {
            daySelected: function() {
              if (this.$firebaseRefs['prevList']) {
                this.$unbind('prevList')
              }
              this.$bindAsArray('prevList', db.ref(`${this.daySelected}`))
            }
          },
          firebase () {
            return {
              list: today    
            }
          }
        };
        </script>