Debounce with remote calls

I implemented a custom DataAdaptor to load data from a remote source, but I couldn't find any debounce support in the AutoComplete component.

Given that a remote request is issued at every key, it looks expensive, to me, in case of remote requests. My feeling is that there's some debounce time anyway, internally (because if you type very quickly, you can see less calls than the actual typed characters), but it would be nice if this value could be configurable.

Thank you.


5 Replies

SP Sureshkumar P Syncfusion Team March 9, 2022 01:57 PM UTC

Hi Andrea,  
 
We checked your reported query. As per your requirement we have created the sample with Debounce technique. 
 
<SfAutoComplete @ref="AutoCompleteObj" TValue="string" TItem="Countries" Placeholder="e.g. Australia" DataSource="@LocalData">  
    <AutoCompleteFieldSettings Value="Name"></AutoCompleteFieldSettings>  
    <AutoCompleteEvents TValue="string" TItem="Countries" Filtering="onInputDebounced"></AutoCompleteEvents>  
</SfAutoComplete>  
  
@code {  
    SfAutoComplete<string, Countries> AutoCompleteObj;  
    public class Countries  
    {  
        public string Name { getset; }  
        public string Code { getset; }  
    }  
  
    List<Countries> LocalData = new List<Countries> {  
    new Countries() { Name = "Australia", Code = "AU" },  
    new Countries() { Name = "Bermuda", Code = "BM" },  
    new Countries() { Name = "Canada", Code = "CA" },  
    new Countries() { Name = "Cameroon", Code = "CM" },  
    new Countries() { Name = "Denmark", Code = "DK" }  
  };  
  
  
    public void onFiltering(Syncfusion.Blazor.DropDowns.FilteringEventArgs args)  
    {  
        args.PreventDefaultAction = true;  
        var query = new Query();  
        if (args.Text != "")  
        {  
            query = new Query().Where(new WhereFilter()  
            {  
                Field = "Name",  
                value = args.Text,  
                Operator = "Contains",  
                IgnoreCase = true  
            });  
        }  
        this.AutoCompleteObj.Filter(LocalData, query);  
    }  
    Action<Syncfusion.Blazor.DropDowns.FilteringEventArgs> onInputDebounced;  
  
  
    protected override void OnInitialized()  
    {  
        onInputDebounced = DebounceEvent<Syncfusion.Blazor.DropDowns.FilteringEventArgs>(e => this.onFiltering(e), TimeSpan.FromMilliseconds(300));  
        base.OnInitialized();  
    }  
    Action<T> DebounceEvent<T>(Action<T> action, TimeSpan interval)  
    {  
        return Debounce<T>(arg =>  
        {  
            InvokeAsync(() =>  
            {  
                action(arg);  
                StateHasChanged();  
            });  
        }, interval);  
    }  
    Action<T> Debounce<T>(Action<T> action, TimeSpan interval)  
    {  
        if (action == nullthrow new ArgumentNullException(nameof(action));  
  
        var last = 0;  
        return arg =>  
        {  
            var current = System.Threading.Interlocked.Increment(ref last);  
            Task.Delay(interval).ContinueWith(task =>  
            {  
                if (current == last)  
                {  
                    action(arg);  
                }  
            });  
        };  
    }  
}  
 
 
 
Regards, 
Sureshkumar P 



AB Andrea Bioli March 9, 2022 08:26 PM UTC

:-) It's a nice piece of code, but it's not my case. I adapted it to work with my custom remote adapter, but the filtering happens after data is loaded from the server, so it doesn't change the remote behavior (if I adapted the code to my case correctly).

Andrea Bioli



AB Andrea Bioli March 9, 2022 08:50 PM UTC

Sorry, reading better the code, I think I understand now the principle, and the workflow.

I remain with the problem of having my Autocomplete object built in the following way:


<SfAutoComplete @ref="AutoCompleteObj" TValue="string" TItem="LookupValue" Placeholder="...start typing to search">
<SfDataManager AdaptorInstance="@typeof(TEntity)" Adaptor="Adaptors.CustomAdaptor"></SfDataManager>
<AutoCompleteFieldSettings Value="Description" />
<AutoCompleteEvents TValue="string" TItem="LookupValue" ValueChange="onChange" Filtering="onInputDebounced"></AutoCompleteEvents>
</SfAutoComplete>


(formatting is not good, sorry)

And the last line of onFiltering takes data from a local variable. Where can I find what's returned from the CustomAdaptor (that by the way is already filtered with the text...).

Thank



AB Andrea Bioli March 10, 2022 01:53 AM UTC

I'm making progresses.


Now, using the debouncing, I can see that (after the first run, where for each key there is a remote call, very strange), with a very high debouncing time (2000 milliseconds) the remote calls are done with that interval.


This is the code for my (remote custom adaptor) case:




private void onFiltering(FilteringEventArgs args)

{

args.PreventDefaultAction = true;


var query = new Query();

if (args.Text != "")

{

query = new Query().Where(new WhereFilter()

{

    Field = "Name",

    value = args.Text,

    Operator = "Contains",

    IgnoreCase = true

});

}

this.AutoCompleteObj.Filter(this.AutoCompleteObj.DataSource, query); // <-- modified call

}


But I still have a weird case, where there is no refresh of the drop down list after each call.

You can see in the picture that there is a content in the input box, but the drop down list still shows the result of the previous, and so on.


Is there some code I can execute to refresh the list?

Thanks again.

Andrea Bioli


P.S.: I cannot upload the zipped picture, I don't know why: I hope you can get the point anyway...



Attachment: Autocomplete_c4622dca.zip


SP Sureshkumar P Syncfusion Team March 11, 2022 09:30 AM UTC

Hi Andrea, 
There is currently no support in the AutoComplete component for making a single request to the server while typing a character in the input rather than multiple requests. So, we have considered the requested requirement as a feature at our end and this support will be included in any one of our upcoming releases. You can track the status of this feature from the below feedback. 
 
Regards, 
Sureshkumar P 


Loader.
Up arrow icon