Issue with chaining promises + Datasets

There’s something strange with my code and I still can’t figure it out.

I’m trying to randomly sort items from a collection to display them in a repeater.
The whole process triggers onReady of my dataset and does the following:

  1. Query the Live Collection where I have the data to be sorted.
  2. Delete all records in the Temporary Collection.
  3. Add all records from the Live Collection to the Temporary Collection.
  4. Refresh the Dataset.
  5. Display the Repeater.

THE CODE

function deleteRecord(collectionName) {
	return new Promise((resolve, reject) => {
		console.log("**Deleting**");
		$w("#preloader").show();
		$w("#businessesRepeater").hide();
		const numberOfItems = $w('#sortingDataset').getTotalCount();
		console.log("Items to Delete: " + numberOfItems);
		$w('#sortingDataset').getItems(0, numberOfItems)
			.then(results => {
				const elements = results.items;
				elements.forEach(item => {
					wixData.remove(collectionName, item._id);
				});
			})
			.then(() => wixData.query("Members").count())
			.then((results) => resolve(console.log("Records in the Collection: " + results)))
			.catch((err) => reject(console.log("Error Deleting: " + err)));
	});
}

function addRecord(collectionName, sortedItems) {
	return new Promise((resolve, reject) => {
		console.log("**Adding**");
		for (var item in sortedItems) {
			wixData.insert(collectionName, sortedItems[item])
				.then((results) => {
					resolve(console.log("Record Added: " + results._id));
				})
				.catch((err) => {
					reject(console.log("Error Adding: " + err));
				});
		}
	});
}

export function sortingDataset_ready() {
	console.log("On Ready Dataset Items: " + $w('#sortingDataset').getTotalCount());
	wixData.query("MemberProfile")
		.ascending("_id")
		.find()
		.then((results) => {
			items = results.items;
			items = shuffle(items);
		})
		.then(() => deleteRecord("Members"))
		.then(() => $w('#sortingDataset').refresh())
		.then(() => addRecord("Members", items))
		.then(() => $w('#sortingDataset').refresh())
		.then(() => {
			console.log("Dataset Refreshed - Items: " + $w('#sortingDataset').getTotalCount());
			$w("#preloader").hide();
			$w("#businessesRepeater").show();
		})
		.catch((error) => {
			console.log("Error Message: " + error.message);
			console.log("Error Code: " + error.code);
		});
}

THE ISSUE
I get some funny results every time I run the code…


For some reason the delete function is not done when the add function starts to work??
But when the Dataset gets refreshed it shows 9 items…
And the repeater stayed with 6… (o.O)


I would appreciate some help :slight_smile:

Got it working only with code discarding the datasets… but interested in understanding what was happening with the code I wrote above #WixCoders?

Hi Felipe,

I believe the issue is with this line:

wixData.remove(collectionName, item._id)

wixData.remove returns a promise, so you will have to await until its resolved to make sure the items were completely removed before proceeding to add items in the next function.

Thank you Ido :slight_smile:

But isn’t that line wrapped within a then( ) statement and followed by another then( )?

 .then(results => { 
 const elements = results.items; 				
 elements.forEach(item => { 					
 wixData.remove(collectionName, item._id); }); }) 
 .then(() => wixData.query("Members").count()) 

Hi Felipe,

Each time wixData.remove is fired a promise is created.
The then() after remove() only awaits the forEach iteration to finish processing, disregarding the promises made by the wixData.remove call. Therefore we end up with more items than we expect when calling count()

Try this method:

function deleteRecord(collectionName) {
 return new Promise((resolve, reject) => {
        console.log("**Deleting**");
 const numberOfItems = $w('#dataset1').getTotalCount();
        console.log("Items to Delete: " + numberOfItems);
        $w('#dataset1').getItems(0, numberOfItems)
            .then(results => {
                   const elements = results.items;
                   const promises = elements.map(item => wixData.remove(collectionName, item._id))
                   return Promise.all(promises)
            })
            .then(() => wixData.query("Members").count())
            .then((results) => resolve(console.log("Records in the Collection: " + results)))
            .catch((err) => reject(console.log("Error Deleting: " + err)));
    });
}

Let me know if it works for you.

Thanks.
Ido

Thank you Ido! I didn’t know the Promise.all( ) method. Amazing!