Reputation: 431
I am trying to retrieve the data from cloud firestore database. But I got an error,
[Vue warn]: Error in render: "TypeError: product.data is not a function"
I want to show the each product name and price in my table.
But I have no idea why this issue comes up. So I hope somebody can help me out.
If I don't use data() in the vue template, I can see all the data as I expected.
<template>
<h3>Product List</h3>
<div class="table-responsive">
<table class="table">
<thead>
<tr>
<th>Name</th>
<th>Price</th>
<th>Modify</th>
</tr>
</thead>
<tbody>
<tr v-for="(product, index) in products" :key="index">
<td>{{ product.data().name }}</td>
<td>{{ product.data().price }}</td>
<td>
<button @click="editProduct(product)" class="btn btn-primary">Edit</button>
<button @click="deleteProduct(product.id)" class="btn btn-danger">Delete</button>
</td>
</tr>
</tbody>
</table>
</div>
</template>
<script>
import { fb, db } from '../firebase'
export default {
name: 'Products',
props: {
msg: String
},
data () {
return {
products: [],
product: {//object
name: null,
price: null
}
}
},
methods: {
editProduct(product) {
$('#edit').modal('show')
},
readData() {
db.collection("products").get().then((querySnapshot) => {
querySnapshot.forEach((doc) => {
this.products.push(doc.data());
});
});
},
saveData() {
// Add a new document with a generated id.
db.collection("products").add(this.product)
.then((docRef) => {
console.log("Document written with ID: ", docRef.id);
this.product.name = "",
this.product.price = ""
this.readData()
})
.catch(function(error) {
console.error("Error adding document: ", error);
});
}
},
created() {
this.readData();
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang="scss">
</style>
Upvotes: 0
Views: 1498
Reputation: 487
I will have to agree with @Mostafa, the naming convention is not very readable. Your error is telling you that you are trying to invoke a function that is not a function or does not exist in your data.
Change:
<td>{{ product.data().name }}</td>
<td>{{ product.data().price }}</td>
To:
<td>{{ product.name }}</td>
<td>{{ product.price }}</td>
This should fix it, as you are iterating over the products list (of which isn't clear), so i advise you should change:
<tr v-for="(product, index) in products" :key="index">
<td>{{ product.name }}</td>
<td>{{ product.price }}</td>
<td>
<button @click="editProduct(product)" class="btn btn-primary">Edit</button>
<button @click="deleteProduct(product.id)" class="btn btn-danger">Delete</button>
To:
<tr v-for="(productItem, index) in products" :key="index">
<td>{{ productItem.name }}</td>
<td>{{ productItem.price }}</td>
<td>
<button @click="editProduct(productItem)" class="btn btn-primary">Edit</button>
<button @click="deleteProduct(productItem.id)" class="btn btn-danger">Delete</button>
Upvotes: 2
Reputation: 302
Your code is very confusing. I don't understand why you are calling data method on product and why you have product and products in your data when you just need one. So i'm assuming Vue is mixing product in your for loop and the product object in your data. So either change the product name in your for loop to something else:
v-for="(item,index) in products"
or change product in your data (just remove it if you can) cause it doesn't have any data method in it.
Upvotes: 0