Hello all,
We’re building our own ecommerce / ordering facility and we’ve rolled out our own cart page using a dataset bound to a repeater (with product title, unit price, and qty input so users can amend quantities of items). We have code which iterates the records in the dataset to produce a total cost of all items.
We have then set the text property of a text element on the page with this value.
However… when changing the qty input and forcing a save() on the dataset, it takes a second refresh/ recalc for the total to display correctly on this text element.
The simple answer isn’t simply getting the code to do the save twice and calculation twice as you have to mouse click etc. to get it to refresh.
If anyone has any ideas on this, it’d be very much appreciated.
Without seeing any code it is more guess work.
However, after using save in your code, have you simply tried using refresh in your code?
https://www.wix.com/corvid/reference/wix-dataset.Dataset.html#refresh
Thanks for the reply. Here’s what we’re working with at the moment if that helps. First part relates to filtering the cart page according to one of two product ranges (‘statues’ or ‘decor’)
import wixData from ‘wix-data’;
import wixLocation from ‘wix-location’;
$w.onReady( async function () {
var business = “”;
let query = wixLocation.query;
if (query.b === ‘d’)
business = “Decor”;
else if (query.b === ‘s’)
business = “Statues”;
else
business = “”;
$w(‘#text11’).text = “Viewing Sparta " + business + " cart”;
$w(‘#dynamicDataset’).onReady(() =>
{
$w(“#dynamicDataset”).setFilter( wixData.filter()
.eq(“collectionSlug”, “sparta-” + business.toLowerCase())
);
console.log("Filtered dataset for → " + “sparta-” + business.toLowerCase());
});
$w(‘#repeater2’).onItemReady ( ($w, itemData) => {
// Set the action that occurs when a user clicks the remove button
$w(‘#removeButton’).onClick( async (event) => {
await $w(‘#dynamicDataset’).remove;
});
$w(“#qtyInput”).onKeyPress((event) => {
if (event.key === “Enter” & Number($w(“#qtyInput”).value > 0)){
$w(‘#dynamicDataset’).save();
}
});
});
});
async function RefreshCart()
{
console.log(“RefreshCart entered”);
let CartTotals = {
totalItems: 0,
totalQuantity: 0,
totalCost: 0
};
var dataset = $w(‘#dynamicDataset’);
let count = dataset.getTotalCount(); // No. of items in dataset //
console.log("count: " + count);
dataset.getItems(0, count) // Get all items //
//.include(“productId”)
.then((results) => {
if (results.length === 0)
{
console.log(“no results!!!”);
}
else
{
let items = results.items;
CartTotals.totalItems = items.length;
items.forEach(item => {
if (item.collectionSlug === ‘sparta-statues’)
{
CartTotals.totalQuantity = CartTotals.totalQuantity + Number(item.quantity);
CartTotals.totalCost = CartTotals.totalCost + (Number(item.quantity) * Number(item.productId.price));
}
});
console.log(CartTotals);
$w(‘#text20’).text = “£” + Number.parseFloat(CartTotals.totalCost).toFixed(2);
$w(‘#text21’).text = “£” + Number.parseFloat(CartTotals.totalCost * 0.2).toFixed(2);
$w(‘#text22’).text = “£” + Number.parseFloat(CartTotals.totalCost * 1.2).toFixed(2);
}
})
. catch ((err) => {
console.log(err);
});
}
export async function GetCartTotals(dataset) {
let CartTotals = {
totalItems: 0,
totalQuantity: 0,
totalCost: 0
};
let count = dataset.getTotalCount(); // No. of items in dataset //
dataset.getItems(0, count) // Get all items //
//.include(“productId”)
.then((results) => {
let items = results.items;
CartTotals.totalItems = items.length;
items.forEach(item => {
CartTotals.totalQuantity = CartTotals.totalQuantity + Number(item.quantity);
CartTotals.totalCost = CartTotals.totalCost + (Number(item.quantity) * Number(item.productId.price));
});
return (CartTotals);
})
. catch ((err) => {
console.log(err);
});
export function qtyInput_blur(event) {
console.log(“blur()”);
}
export async function dynamicDataset_afterSave() {
console.log(“afterSave()”);
RefreshCart();
}
export function dynamicDataset_ready() {
console.log(“ready()”);
RefreshCart();
}
export async function dynamicDataset_itemValuesChanged() {
console.log(“itemValuesChanged()”);
await $w(‘#dynamicDataset’).save();
}
export async function qtyInput_click(event) {
console.log(“Click()”);
await $w(‘#dynamicDataset’).save();
RefreshCart();
}
export function updateButton_click(event) {
RefreshCart();
}
The dataset save() and getItems() functions are both Promises, meaning it can take a while before the .then() gets invoked.
Suggestion:
Maintain a global variable that gets the total cost of the items on page load ($w.onReady()). Then, everytime someone updates the quantity input, you can immediately deduct/add the product’s price from/to the total cost and show the resulting price. At the same time, go through the save/update process. As this would result in the same price anyway, the only thing you’re getting from this is the benefit of faster visual updates for the user.
Hope this helps.
Thanks very much for this. I’ll try it out.