setSort() appears to have some kind of delayed action - how can I prevent this?

I’m trying to enable users to choose how data displayed in a repeater are sorted. They have dropdowns from which they can choose the field to sort on and whether to sort ascending or descending, and a search button that allows them to update the repeater with the first few items of data in their given sort. All that seems to be working well, except for one problem.

Any time I click the search button, a few seconds later the repeater’s data changes and shows the most recently added items - that is, the first few items according to the default sort. A few seconds after THAT, the data changes again to the first few items according to the user’s sort parameters. It’s as if all the data are being returned and plugged into the repeater immediately, then sorted and plugged in again. I can live with the delay, but I would like the repeater not to change at all until the correctly-sorted data are available.

Here’s a link to the page so you can see what’s going on: https://www.sfcknox.org/people

And here’s the code I’m running. The problem occurs when the search() function runs. Sorry if it’s not formatted well - the formatting doesn’t seem to have been copied from the original, but I restored it as well as I could:

import wixData from 'wix-data';
import wixUsers from 'wix-users';

$w.onReady(function () {
    // Run the search function when the user clicks search...
    $w('#button15').onClick(search); 
    search(); // and also when the page loads
});

function search() {
    // Set the dataset's sort according to the user's choices
    let sort = wixData.sort();
    if ($w("#dropdown20").value === "Ascending") 
        sort = sort.ascending($w("#dropdown19").value);
    else sort = sort.descending($w("#dropdown19").value);
    $w("#dynamicDataset").setSort(sort);
    // Build a query according to what, if any, criteria the user set
    let query = buildQuery();

    // Search the database and plug results into the repeater
    query.find()
    .then( (results) => {
        $w('#repeater3').data = results.items;
    });
}
function buildQuery() {
    // This page always searches the people collection
    let query = wixData.query("People"); 
    // Call updateQuery for each input - it will add a criterion 
    // to the query if the user typed anything in that input
    query = updateQuery(query, $w('#input5'), $w('#dropdown13'), "firstName");
    query = updateQuery(query, $w('#input6'), $w('#dropdown14'), "lastName");
    query = updateQuery(query, $w('#textBox9'), $w('#dropdown15'), "phones");
    query = updateQuery(query, $w('#textBox10'), $w('#dropdown16'), "emails");
    query = updateQuery(query, $w('#textBox11'), $w('#dropdown17'), "urLs");
    query = updateQuery(query, $w('#textBox12'), $w('#dropdown18'), "comments");
    // Set a limit for the query, if the user entered one
    const limit = parseInt($w("#input7").value, 10);
    if (limit) query = query.limit(limit);
    return query;
}
function updateQuery(query, input, dropdown, field) {
    // what will be returned. Starts identical to the original.
    let newQuery = query; 
    // If the user entered something for this field...
    if (input.value) { 
        // call startsWith, endsWith or contains on the query...
        switch(dropdown.value) { 
            case "start":
                newQuery=query.startsWith(field, input.value)
                break;
            case "contain":
                newQuery=query.contains(field, input.value)
                break;
            case "end":
                newQuery=query.endsWith(field, input.value)
                break;
        }
    }
    return newQuery; // Return the new, possibly modified query
}

I haven’t tested searching with specific criteria (like for people with a specific last name) and sorting together yet, because I haven’t gotten sorting working to my satisfaction on its own. So I wouldn’t worry about testing the search inputs.

Hi Amy,

Basically, there are two approaches to populating and filtering repeaters: 1) using a dataset and the setFilter command or 2) doing a straight query using wixData.query and assigning the data with the query results as you are doing.

As is commonly done as people are getting familiar with how wix-data and wix-dataset work, it looks like you are trying to simultaneously use both approaches and are bound to get inconsistent results. You seem to be comfortable enough writing code that I’m thinking that you should do it the direct query way. Doing it that way, you would use the onItemReady or forEachItem functions to assign the repeater elements their values instead of assigning dataset fields. Then set up your sort in the query with ascending function instead of using setSort on the dataset.