I have massively improved over my last question, but I am stuck again after some days of work.
Using Vue, Vue-router, Vuex and Vuetify with the Data on Googles Could Firestore
I want to update my data live, but i cannot find a way to do this. Do i need to restructure, like moving products and categories into one collection? Or is there any bind or query magic to get this done. As you can see below, it loads the data on click quite well, but I need the live binding 'cause you could have the page open and someone could sell the last piece (amountLeft = 0). (And a lot of future ideas).
My data structure is the following:
categories: {
cat_food: {
name: 'Food'
parentCat: 'nC'
},
cat_drinks: {
name: 'Food'
parentCat: 'nC'
},
cat_beer: {
name: 'Beer'
parentCat: 'cat_drinks'
},
cat_spritz: {
name: 'Spritzer'
parentCat: 'cat_drinks'
},
}
products: {
prod_mara: {
name: 'Maracuja Spritzer'
price: 1.5
amountLeft: 9
cat: ['cat_spritz']
},
prod_capp: {
name: 'Cappuccino'
price: 2
cat: ['cat_drinks']
},
}
The categories and the products build a tree. The GIF shows me opening the categories down to show a product. You see that it's a product when you have a price tag. You can see there are two categories that have the same parent (cat_drinks). The product prod_capp is also assigned to the category and shown side by side to the categories.
I get the data currently this way:
catsOrProd.js
import { catsColl, productsColl } from '../firebase'
const state = {
catOrProducts: [],
}
const mutations = {
setCats(state, val) {
state.catOrProducts = val
}
}
const actions = {
// https://vuefire.vuejs.org/api/vuexfire.html#firestoreaction
async bindCatsWithProducts({ commit, dispatch }, CatID) {
if (CatID) {
// console.log('if CatID: ', CatID)
await Promise.all([
catsColl.where('parentCat', '==', CatID).orderBy('name', 'asc').get(),
productsColl.where('cats', 'array-contains', CatID).orderBy('name', 'asc').get()
])
.then(snap => dispatch('moveCatToArray', snap))
} else {
// console.log('else CatID: ', CatID)
await Promise.all([
catsColl.where('parentCat', '==', 'nC').orderBy('name', 'asc').get(),
productsColl.where('cats', 'array-contains', 'nC').orderBy('name', 'asc').get()
])
.then(snap => dispatch('moveCatToArray', snap))
}
},
async moveCatToArray({ commit }, snap) {
const catsArray = []
// console.log(snap)
await Promise.all([
snap[0].forEach(cat => {
catsArray.push({ id: cat.id, ...cat.data() })
}),
snap[1].forEach(cat => {
catsArray.push({ id: cat.id, ...cat.data() })
})
])
.then(() => commit('setCats', catsArray))
}
}
export default {
namespaced: true,
state,
actions,
mutations,
}
This is a part of my vue file that is showing the data on screen. I have left out the unnecessary parts. To open everything a have a route with props and clicking on the category sends the router to the next category. (this way i can move back with browser functionality). Sale.vue
<template>
...........
<v-col
v-for="catOrProduct in catOrProducts"
:key="catOrProduct.id"
@click.prevent="leftClickProd($event, catOrProduct)"
@contextmenu.prevent="rightClickProd($event, catOrProduct)">
....ViewMagic....
</v-col>
............
</template>
<script>
.........
props: {
catIdFromUrl: {
type: String,
default: undefined
}
},
computed: {
// https://stackoverflow.com/questions/40322404/vuejs-how-can-i-use-computed-property-with-v-for
...mapState('catOrProducts', ['catOrProducts']),
},
watch: {
'$route.path'() { this.bindCatsWithProducts(this.catIdFromUrl) },
},
mounted() {
this.bindCatsWithProducts(this.catIdFromUrl)
},
methods: {
leftClickProd(event, catOrProd) {
event.preventDefault()
if (typeof (catOrProd.parentCat) === 'string') { // when parentCat exists we have a Category entry
this.$router.push({ name: 'sale', params: { catIdFromUrl: catOrProd.id } })
// this.bindCatsWithProducts(catOrProd.id)
} else {
// ToDo: Replace with buying-routine
this.$refs.ProductMenu.open(catOrProd, event.clientX, event.clientY)
}
},
}
</script>
from Vue, firestore: how to display LIVE data after merging collections
No comments:
Post a Comment