Intermittent wixData.remove Problem

I have put together a simple demonstration of a problem that I’m facing when using a repeater in conjunction with wixData. I realise some may suggest using a dataset, but my real-world scenario is more complex hence the need for linking the repeater to the results of a wixData query. The problem I am facing is that sometimes (not always) when clicking a button to remove an item from the repeater data, the removal takes place, but refreshing the data in the repeater still gets the deleted item even though the function to get the repeater data is being called AFTER the promise return of the wixData.remove() function!

If you want to test it out for yourself you can give it a try here: https://astutesystems.wixsite.com/testsite/test-repeater

Here are the details of how it is working… I have a simple repeater on a page as shown below


This will be linked to data from a dataset as shown here…


The relevant code for the page is as follows:

import wixData from ‘wix-data’;
import wixWindow from ‘wix-window’;
import uuid from ‘uuid’;

var masterID = ‘31068ef7-fe5e-4e2d-9d7a-5796966edaf7’;

$w.onReady( function () {
$w(‘#repeater’).onItemReady(repeater_itemReady);
$w(‘#btnAddData’).onClick(btnAddData_click);
$w(‘#btnDelete’).onClick(btnDelete_click);
getRepeaterData();
});

function repeater_itemReady($item, itemData, index) {
$item(‘#lblHeading’).text = itemData.heading;
$item(‘#lblDetails’).text = itemData.details;
}

function getRepeaterData() {
return new Promise((resolve, reject) => {
wixData.query(‘repeater-test’)
.eq(‘masterId’, masterID)
.descending(‘_createdDate’)
.find()
.then((results) => {
console.log(‘getRepeaterData returned ’ + results.items.length + ’ rows from dataset’);
$w(‘#repeater’).data = results.items;
if ($w(‘#repeater’).hidden) {
$w(‘#repeater’).show();
}
})
. catch ((err) => {
console.error(err);
reject(err);
});
});
}

function btnDelete_click(event) {
var itemData = $w(‘#repeater’).data.find((element) => {
return element._id === event.context.itemId;
});

wixWindow.openLightbox('Confirm Removal') 
.then((data) => { 

if (data.result) {
console.log('About to remove ’ + itemData.heading);
wixData.remove(‘repeater-test’, itemData._id)
.then((results) => {
console.log(results);
getRepeaterData();
})
. catch ((err) => {
console.log(err);
});
}
});
}

One of the ways that I am testing this is using the console to see when an item is being removed and then how many items the getRepeaterData() function finds from the dataset. In theory, after removing an item there should be one less than before (most of the time this is the case)… but here is an example of the intermittent problem - the getRepeaterData() function finds 4 records… 1 is deleted then it again finds 4 records!


A simple refresh of the page then shows just the expected 3 records.

I’m really not sure what’s going on and would appreciate any thoughts/suggestions. Is there a genuine error with the wixData.remove function? Is its promise being resolved before the row is actually removed from the dataset? Would this perhaps be less likely to be a problem if the removal code was moved to a backend function?

Thanks in advance

A couple possibilities:

You should use onItemRemoved() to properly handle the Repeater item that you are removing.

or…

In the getRepeaterData() function, set the Repeater’s data like this:

$w('#repeater').data = [];
$w('#repeater').data = results.items;

First set the Repeater’s data to empty. Then when you set it to results.items, it forces the onItemReady() function to handle all of the “new” data. Otherwise, you still have items that exist and they are not properly handled.

Thanks for the suggestion Yisrael. I had already tried setting the repeater data to an empty array first but that didn’t help. If you check the details of the console messages, it’s clearly not the repeater itself which is at fault. I’m logging before the removal of the record, then the results of the item removed showing that it was correctly found, then logging the number of items found by the query of that same dataset which shows no change in the number of records in the dataset. The repeater simply binds to those results, so it’s not that the repeater isn’t updating, but rather that the query to get the data is still returning the deleted item.

It does seem to be a momentary thing - a refresh of the page sorts it out, but that’s not a solution.

Any other ideas? It’s almost like removing the item from the database was somewhat throttled and so we’re still getting the item in a query which is run very very soon after the removal.

Please post the editor URL of your site. Only authorized Wix personnel can get access to your site in the editor. Please include the name of the page involved.

@yisrael-wix Here you are… https://editor.wix.com/html/editor/web/renderer/edit/40160dfb-b176-4d28-886e-de4734f37cd4?metaSiteId=f86f7bd1-24dd-42c3-ab39-5b9a455950ba&editorSessionId=102a3a73-314a-499c-8551-eec23292e9d9&referralInfo=dashboard
The page in question is ‘Test Repeater’
I have also added another test version - Test Repeater 2 which uses backend functions instead… so far that hasn’t given any issues but I’m still testing.

Quick update - I have seen the same behaviour even when the wixData functions are held in the backend (see that Test Repeater 2 page). It doesn’t happen often - maybe once in 30 deletes - but the same as above where the deleted item appears to be in the results of the query() even though that’s after the remove() promise suggests it has been successfully deleted.

@peteleyland It’s really a Repeater issue and not so much a database issue. I’ll take a look.

@yisrael-wix Take a look at this console data:


getRepeaterData is showing that the length of the wixData.query() results.items is 3.
Next after clicking delete, it says we’re about to remove an item from the data collection and shows the result of wixData.remove() - the result being the item removed.
Next we re-run getRepeater data and it still says that the length of the results.items from the wixData.query() is 3.

At no point am I logging any property of the repeater itself - those are all values associated with wixData methods.

@yisrael-wix
I’m not 100% sure, but this problem seems to be most noticeable on a new data collection. When the data collection is more in use it seems that perhaps its performance is improved and this issue doesn’t show up.

I set up a new page (Test No Repeater) with the same functionality in terms of getting the count of records belonging to the current masterID in a new collection called repeater-test2 (same structure as the previous one).

This time the page doesn’t have a repeater on it anywhere… there is a method to display the number of records returned by the query:

function populateCount() {
    wixData.query('repeater-test2')
    .eq('masterId', masterID)
    .descending('_createdDate')
    .find()
    .then((results) => {
        console.log('Query returned ' + results.items.length + ' rows from dataset');
        $w('#lblRecCount').text = 'Record Count: ' + results.items.length.toString();
        myData = results.items;
    })
    .catch((err) => {
        console.error(err);
    });
}

And a delete button which calls the following function:

function btnDelete_click(event) {
    console.log('About to remove ' + myData[0].heading);

    wixData.remove('repeater-test2', myData[0]._id)
    .then((results) => {
        console.log('Item removed');
        console.log(results);
        populateCount();
    })
    .catch((err) => {
        console.log(err);
    });
}

There were 4 items, which I removed one after the other, making sure to see the change in record count before clicking the delete button again. In the screenshot below you can see that the record count was 3, then a record was removed so that the ‘Query returned 2 rows from the dataset’. Then on clicking delete again, it removed another item but the query still says it returned 2 items from the data collection when there should now only be 1. Refreshing the page gave me a count of 1, so the item was definitely removed… it’s almost like there is a latency issue:

OK, I think I do see something. Doesn’t happen very often, but from time to time. I’m reporting this to QA for evaluation.

Thanks @yisrael-wix - please do let me know what they come back with on this. For the most part I think if a collection sees high usage it might not be an issue, but I have a situation where a particular collection might not get updated so regularly, and it wouldn’t be ideal if the query data doesn’t get updated to reflect the user’s interaction.

QA informed me that they’ve opened a problem ticket for this issue.

@yisrael-wix did they manage to resolve it? I think I saw a message from you saying they had done something? I’m still seeing the same issue

@peteleyland I don’t know. I got some notice from them that it’s OK, but it seems to me that what they think is OK isn’t what I think is OK. I need to clear this up. Sorry. I’ll get back to you on this.

@yisrael-wix Hi Yisrael,

In my opinion the issue described in this post is not related to repeaters behavior. I have similar problem with almost all wixData APIs. According to my observation, the collections are not guaranteed to be updated after wixData API resolved properly and consequent operation may fail.
For me it is major issue, since I can’t be sure my flows are executed as expected and fail sporadically.

To demonstrate same problem without repeaters, please take a look at the following example:
https://dmitrybi32.wixsite.com/issue-reproduce/wix-data-issue
When pressing on the button, the following flow is run:
wixData.insert record into collection with current time in ‘title’ column. Once promise resolves, wixData.update same record setting “valid” string to ‘valid’ column. After 20 attempts of running this simple flow, I had 3 of them failing with the following (prints in console):
Error: Item [3c7bf04b-44cf-4ded-a951-df522a1b2b8a] does not exist in collection [wixDataIssue].
After inspecting collection content, I see record with _id which was reported as not existing…

According to my tests, in case of such sporadic failure, if after insert (or other API) I run other query for 3-5 times, it will successfully find the recently added record. So for me it sounds like some timing issue where for example ‘insert’ API resolves some hundred milliseconds before the collection is actually updated. But as you may guess it is just assumption.

On my reproduce site you may find related backend code in WixDataIssue.jsw, collection used for this reproduce is wixDataIssue.

One of very problematic use cases where you may see this bug, is when you need to create some unique item. You check whether collection already has this item, and if it is not a case, you insert it. If same action happens several times (user pressed several times on button instead of single click), then sometimes I have 2 - 5 records created with same ‘unique’ data. The root cause is same as in the reproduce sample I provided - first request creates my unique record, the second request checks that such record doesn’t exist - wix API reports it is not, while actually it was added right now - and then same record added for the second time.

I’ll appreciate your attention on this issue. Please let me know if worth sending this info and reproduce to support as well.

Thanks,
Dima

@yisrael-wix

I just posted an issue that I believe is related here: https://www.wix.com/code/home/forum/community-discussion/members-login-issues-with-safari

I’ve also been have having intermittent database issues on top of the issue I just posted.