Axiol
Axiol

Reputation: 5962

Vuex and API calls

I'm trying to implement Vuex in an app I'm building to learn more about Vue.js. The idea is pretty simple: retrieving user information and a list of items (everything is stored on Firebase).

I get the idea of Vuex, but the tutorials I can find only rely on data stored locally in the store. I can't get my head around how it would work when the data in the store has to be kept in sync with an external database.

Did I totally miss something? or maybe is Vuex not the best solution for that?

Upvotes: 1

Views: 536

Answers (1)

Renaud Tarnec
Renaud Tarnec

Reputation: 83163

If you want "the data in the (Vue.js) store to be kept in sync with an external (Firestore) database", you could do as follows, taking advantage of the onSnapshot() method which "attaches a listener for QuerySnapshot events".

Let's imagine you have a cities collection in your Firestore database, and each document of this collection has a field name, which holds the city name.

First, declare the Firebase config in a firebaseConfig.js file:

firebaseConfig.js

import firebase from 'firebase/app';
import 'firebase/firestore';

// firebase init goes here
const config = {
  apiKey: 'xxxxxxxxxxxxxxxxxx',
  authDomain: 'xxxxxxxxx.firebaseapp.com',
  databaseURL: 'xxxxxxxxxxxxxxxxxx',
  projectId: 'xxxxxxxxxxxxxxxxxx'
};

firebase.initializeApp(config);
const db = firebase.firestore();

export { db };

Then set-up your Vuex store as follows:

store.js

import Vue from 'vue';
import Vuex from 'vuex';

Vue.use(Vuex);

export default new Vuex.Store({
  state: {
    cities: []
  },
  mutations: {
    SET_CITIES(state, val) {
      state.cities = val;
    }
  },
  actions: {
    //You may add here an action that would commit the SET_CITIES mutation
  }
});

Then, modify the main.js file as follows:

main.js

import Vue from 'vue';
import App from './App.vue';
import router from './router';
import store from './store';
const fb = require('./firebaseConfig.js');

Vue.config.productionTip = false;

new Vue({
  router,
  store,
  beforeCreate() {
    fb.db.collection('cities').onSnapshot(querySnapshot => {
      var c = [];
      querySnapshot.forEach(doc => {
        c.push({
          id: doc.id,
          name: doc.data().name
        });
      });
      store.commit('SET_CITIES', c);
    });
  },
  render: h => h(App)
}).$mount('#app');

You are all set! Just try getting the cities array in a Component, as follows:

HelloWorld.vue

<template>
  <div>
    <ul>
      <li v-for="c in cities" v-bind:key="c.id">{{ c.name }}</li>
    </ul>
  </div>
</template>

<script>
import { mapState } from "vuex";
export default {
  name: "HelloWorld",
  computed: {
    ...mapState(["cities"])
  }
};
</script>

and try adding, removing or modifying records in the database.

Upvotes: 2

Related Questions