hjortur17's avatar

VUE returns Promise

Any ideas how I can get VUE to return the price I'm calculating instead of Promise

Here is the code:

price: async function () {
			let priceForDays = 0;
			let finalPrice = 0;

			let prices = await axios.get('/api/prices/get/' + this.booking.luggage.size).then(response => response.data);

			if (this.numberOfDays === 1) {
				priceForDays += prices.base
			} else if (this.numberOfDays >= 2 && this.numberOfDays <= 7) {
				priceForDays += prices.base + (prices.afterOneDay * (this.numberOfDays-1))
			} else if (this.numberOfDays >= 8) {
				priceForDays += 8000 + (prices.afterWeek * (this.numberOfDays-7))
			}

			finalPrice = (priceForDays * this.booking.luggage.numberOfBags);

			return finalPrice;
		},
0 likes
14 replies
tykus's avatar

Is this a computed property?

What you probably need is a watcher, which will handle asynchronous behaviors better than a computed property. Set an initial price key in the Component's data, then add a watcher for whatever piece of data should trigger the change; the watcher function can be asynchronous, and should update the price state on the component.

hjortur17's avatar

Yes, this is a computed property.

I have never worked with watch so I'm not familiar with it. I tried this but it doesn't work:

watch: {
		price: async function () {
			let priceForDays = 0;
			
			let prices = await axios.get('/api/prices/get/' + this.booking.luggage.size).then(response => response.data);

			if (this.numberOfDays === 1) {
				priceForDays += prices.base
			} else if (this.numberOfDays >= 2 && this.numberOfDays <= 7) {
				priceForDays += prices.base + (prices.afterOneDay * (this.numberOfDays-1))
			} else if (this.numberOfDays >= 8) {
				priceForDays += 8000 + (prices.afterWeek * (this.numberOfDays-7))
			}

			this.price = (priceForDays * this.booking.luggage.numberOfBags);
		}
	}
tykus's avatar

You're watching the data property that you are assigning to??? What data should change to cause price to be recalculated?

hjortur17's avatar

The chosen date in the system, basically the numberOfDays computed property.

tykus's avatar
tykus
Best Answer
Level 104

So watch numberOfDays, and recalculate the price:

data () {
	return {
		price: null,
		numberOfDays: 1,
		// ...
	}
}, 

watch: {
		numberOfDays: async function () {
			let priceForDays = 0;
			
			let prices = await axios.get('/api/prices/get/' + this.booking.luggage.size).then(response => response.data);

			if (this.numberOfDays === 1) {
				priceForDays += prices.base
			} else if (this.numberOfDays >= 2 && this.numberOfDays <= 7) {
				priceForDays += prices.base + (prices.afterOneDay * (this.numberOfDays-1))
			} else if (this.numberOfDays >= 8) {
				priceForDays += 8000 + (prices.afterWeek * (this.numberOfDays-7))
			}

			this.price = (priceForDays * this.booking.luggage.numberOfBags);
		}
	}
1 like
hjortur17's avatar

This works! And I think I'm starting to understand how watchers work. But one question, do you have an idea how I could make a watcher for booking.luggage.size?

This is what I have right now, but Vue complains because of an unexpected token .

booking.luggage.size: function () {
			if (this.booking.luggage.size == "regular") {
				this.booking.price = 2000;
			} else if (this.booking.luggage.size == "odd-size") {
				this.booking.price = 2500;
			}
		},

So I have my data set-up like this:

booking: {
				user: {
					name: '',
					email: ''
				},
				
				luggage: {
					size: 'regular',
					numberOfBags: 1
				},
				
				days: {
					dropOff: {
						date: null,
						time: null
					},

					pickUp: {
						date: null,
						time: null
					}
				},

				validation: false,
				price: 2000
			},
tykus's avatar

Use a deep watcher:

booking: {
	deep: true,
	handler () {
		if (this.booking.luggage.size == "regular") {
			this.booking.price = 2000;
		} else if (this.booking.luggage.size == "odd-size") {
			this.booking.price = 2500;
		}
}
}
1 like
hjortur17's avatar

@tykus - So this is how my watch looks like. But numberOfDays doesn't work anymore:

watch: {
		booking: {
			deep: true,
			handler () {
				if (this.booking.luggage.size == "regular") {
					this.booking.price = 2000;
				} else if (this.booking.luggage.size == "odd-size") {
					this.booking.price = 2500;
				}
			}
		},

		numberOfDays: async function () {
			let priceForDays = 0;

			let prices = await axios.get('/api/prices/get/' + this.booking.luggage.size).then(response => response.data);

			if (this.numberOfDays === 1) {
				priceForDays += prices.base
			} else if (this.numberOfDays >= 2 && this.numberOfDays <= 7) {
				priceForDays += prices.base + (prices.afterOneDay * (this.numberOfDays-1))
			} else if (this.numberOfDays >= 8) {
				priceForDays += 8000 + (prices.afterWeek * (this.numberOfDays-7))
			}

			this.booking.price = (priceForDays * this.booking.luggage.numberOfBags);
		}
	}
martinbean's avatar

@hjortur17 Can you explain what it is you’re actually trying to do? Because you seem to be misusing computed properties, so thing we need to take a step back and look at what it is you were actually trying to do, instead of how you are trying to solve it.

hjortur17's avatar

@martinbean - So what I'm doing is a simple booking system. You enter in your name and your dept. date and arrival date. What I'm trying to do is getting the prices from the database and calculating it.

martinbean's avatar

@hjortur17 That’s not something that should be in a computed property, then. Computed properties should be able to return values immediately; not return the value once an asynchronous operation (such as making a HTTP request) has completed.

Instead, you should capture those details from the user (name and dates), and then have a button to calculate the price based on those details. You can disable your form whilst the HTTP request is being executed, and then display the price once you’ve got it from the server.

1 like

Please or to participate in this conversation.