I\'m trying to develop a TextField that update the data on a Firestore database when they change. It seems to work but I need to prevent the onChange event to fire multiple
What about a utility function like:
import 'dart:async';
Function debounce(Function func, int milliseconds) {
Timer timer;
return () { // or (arg) if you need an argument
if (timer != null) {
timer.cancel();
}
timer = Timer(Duration(milliseconds: milliseconds), func); // or () => func(arg)
};
}
Then:
var debouncedSearch = debounce(onSearchChanged, 250);
_searchQuery.addListener(debouncedSearch);
In the future with variable arguments it could be improved.
Have a look at EasyDebounce.
EasyDebounce.debounce(
'my-debouncer', // <-- An ID for this particular debouncer
Duration(milliseconds: 500), // <-- The debounce duration
() => myMethod() // <-- The target method
);
In your widget state declare a controler and timer:
final _searchQuery = new TextEditingController();
Timer _debounce;
Add a listener method:
_onSearchChanged() {
if (_debounce?.isActive ?? false) _debounce.cancel();
_debounce = Timer(const Duration(milliseconds: 500), () {
// do something with _searchQuery.text
});
}
Hook and un-hook the method to the controller:
@override
void initState() {
super.initState();
_searchQuery.addListener(_onSearchChanged);
}
@override
void dispose() {
_searchQuery.removeListener(_onSearchChanged);
_searchQuery.dispose();
_debounce?.cancel();
super.dispose();
}
In your build tree bind the controller to the TextField:
child: TextField(
controller: _searchQuery,
// ...
)