Reputation: 841
I'm trying to calculate total bill (sum of all product*usage) from an object of customerProduct data and display the bill amount. I'm calling a computed method to perform this. The customerProduct data is fetched from a get
api call in the created()
method.
Issue: In the initial render, console shows the following error: [Vue warn]: Error in render: "TypeError: Cannot read property 'PRICE' of undefined"
. Is this because the computation is taking some time and meanwhile when the template html code renders, the customerProductData is not fetched properly?
Also, can using watch
property help here?
Computed method to calculate total bill:
computed:{
billAmount(){
var billAmountWithoutDiscount = 0;
if(typeof(this.customerProductData[0].PRICE) == undefined){
return 0.0
}
else{
for(let i=0;i<this.customerProductData.length;i++){
billAmountWithoutDiscount += this.customerProductData[i].PRICE * this.customerProductData[i].USAGE;
}
return Number((100.0 - this.customerMetaData.discount)*billAmountWithoutDiscount/100).toLocaleString();
}
}
}
GET api call:
methods:{
async init(){
const response = await axios.get("/subscribe/getPresalesPricingMetaData/"+this.customerName)
this.customerProductData = response.data;
// console.log(response.data)
this.getCustomerMetaData();
},
}
customerProduct object:
customerProductData:[
0: {
'PRICE': 10,
'USAGE': 2000
},
1: {
'PRICE': 30,
'USAGE': 230
},
2: {
'PRICE': 50,
'USAGE': 200
},
3: {
'PRICE': 30,
'USAGE': 1000
},
]
The discount value:
customerMetaData:{
'discount': 2.2
}
Upvotes: 0
Views: 1542
Reputation: 841
The issue was indeed that the GET api call was taking time, hence the customerProductData was not getting populated. So when the computed method was called, it did not have any data to work with.
Now if you read the computed method carefully, I actually wrote the code to deal with the above situation using an if
statement to return 0 if the customerProductData was not populated. This didn't work because the condition used was incorrect.
if(typeof(this.customerProductData[0].PRICE) == undefined)
Since, there is no data in customerProductData, the initial access of this.customerProductData[0]
itself fails, so the PRICE
property never gets accessed i.e. not returning undefined
Solution: Check if index 0 exists or not in customerProductData
computed:{
billAmount(){
var billAmountWithoutDiscount = 0;
if(!this.customerProductData.hasOwnProperty(0)){
return 0.0
}
else{
for(let i=0;i<this.customerProductData.length;i++){
billAmountWithoutDiscount += this.customerProductData[i].PRICE * this.customerProductData[i].CONSUMPTION;
}
return Number((100.0 - this.customerMetaData.discount)*billAmountWithoutDiscount/100).toLocaleString();
}
}
}
Upvotes: 0
Reputation: 548
Here is an updated code. Try once.
new Vue({
el: '#app',
data: {
message: "sample mesage",
customerProductData:[
{
'PRICE': 10,
'USAGE': 2000,
'CONSUMPTION': 100
},
{
'PRICE': 30,
'USAGE': 230,
'CONSUMPTION': 200
},
{
'PRICE': 50,
'USAGE': 200,
'CONSUMPTION': 300
},
{
'PRICE': 30,
'USAGE': 1000,
'CONSUMPTION': 400
},
],
customerMetaData: {
'discount': 2.2
}
},
computed: {
billAmount(){
let billAmountWithoutDiscount = 0;
if(typeof(this.customerProductData[0].PRICE) == undefined){
return 0.0
} else {
for(let i=0;i<this.customerProductData.length;i++){
billAmountWithoutDiscount += this.customerProductData[i].PRICE * this.customerProductData[i].CONSUMPTION;
}
return Number((100.0 - this.customerMetaData.discount) * billAmountWithoutDiscount / 100).toLocaleString();
}
}
},
methods:{
async init(){
let that = this;
axios.get("/subscribe/getPresalesPricingMetaData/"+this.customerName).then(function(response){
that.customerProductData = response.data;
that.getCustomerMetaData();
})
},
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<h1>{{ billAmount }}</h1>
</div>
Upvotes: 1