How to get updated results from database in dynamic page

Hello,

I have a database of Tests and each one has a dynamic page where you can upvote for it.

The problem is that when two users are on the dynamic page of the Test and they are trying to upvote for the Test without refreshing the page before, only one user can vote because the other one does not get the new voting parameter.

For example two users (user1 and user2) are on the Test dynamic page and the voting parameter (rating) for the Test is 0.
user1 is upvoting for it and updating the value in the database to 1. And now user2 is trying to upvote as well. The value user2 sees, if the page is not refreshed, is 0. So therefore user2 updated the value to 1 as well.
In the end the value ends up being 1.

Any ideas how to fix it?

My code below:

export function upvote_click(event) {
	$w("#testsDatasetDynamic"). refresh();
	let test= $w("#testsDatasetDynamic"). getCurrentItem();
	
	// I saved an array of all voters so users can't vote twice.
	let upvoters = test.upvoters;
	let userId = wixUsers. currentUser. id;
	
	// canVote is a value that is determined in the beginning of the onReady() function
	// by searching the Test's upvoters array
	if(canVote) {
		upvoters.push(userId);
		item.upvoters = upvoters;
		item. rating = item.rating + 1;
        	wixData. update("Test", item). then(() => { 
			$w("#testsDatasetDynamic"). refresh();
			canVote = false;
		});
	}
}

Thanks.

Hi Dan,

I suggest that right before you run the update function, get the latest value from the DB again, add 1 and only then run the update.

This will solve most of the cases but not all as there is a slight change two users are running the same code exactly on the same second. So if you want to avoid this too you need to create some kind of lock on the server side. For instance, right before getting the value once again, lock the update by writing something to a DB table. After the update release this lock. Also check in your code that if the lock is on you cannot run the get/add 1/update commands but wait for the lock to come off first. The lock time should be for a a maximum of a few seconds.

Good Luck,
Asaf

The Ratings by User example shows how you can avoid conflicts like this. It has a separate collection of ratings that has 3 main fields: userId, itemId, rating. In your case, you would have a rating of either 0 or 1, and the fields would be userId, testId, upvote (0 or 1). By keeping the upvotes in a separate collection, you will avoid the concurrent user problem.

Thank you, I followed what they did there and it worked.

yes I did that but it still did not receive the correct value