Dart: cancelable post delay / future
Solution 1
You can achieve cancelling the Future
async operation by using CancelableOperation
.
Here is an example (p.s I simplified your method signature for me to test it easily)
CancelableOperation cancellableOperation;
Future<dynamic> fromCancelable(Future<dynamic> future) async {
cancellableOperation?.cancel();
cancellableOperation = CancelableOperation.fromFuture(future, onCancel: () {
print('Operation Cancelled');
});
return cancellableOperation.value;
}
Future<dynamic> getTranslation(String query, String from, String to) async {
return Future.delayed(const Duration(milliseconds: 1000), () {
return "Hello";
});
}
On Text Changed Listener:
onTextChanged() {
fromCancelable(getTranslation("query", "EN", "TR")).then((value) {
print("Then called: $value");
});
}
Sample output:
I/flutter ( 7312): Operation Cancelled
I/flutter ( 7312): Operation Cancelled
I/flutter ( 7312): Operation Cancelled
I/flutter ( 7312): Operation Cancelled
I/flutter ( 7312): Then called: Hello
Solution 2
Yes there is, it is called Timer
https://api.dartlang.org/stable/2.3.1/dart-async/Timer-class.html
You can delay execution as well as cancel the trigger.
Admin
Updated on December 11, 2022Comments
-
Admin over 1 year
I am new to flutter and I want to translate some text from an
InputField
by calling an API. However I don't want to call it on every key stroke, but instead only when the user paused typing.On Android I would just use the
Handler
class withpostDelay()
with beforehand callingremoveAllCallbacksAndMessages(null)
. Is there a way to do something similar on Dart?Here is my current code:
Future<String> getTranslation(String query, Language from, Language to) async { // cancel here if a call to this function was less than 500 millis ago. return Future.delayed(const Duration(milliseconds: 500), () { return _translator.translate(query, from: from.code, to: to.code) }); }
Edit 1
I'm calling the code from my Bloc like so:
@override Stream<State> mapEventToState(Event event) async* { if (event is QueryChangeEvent) { yield TextTranslationChangeState( query: event.query ?? "", translation: await _repo.getTranslation(event.query, currentState.fromLang, currentState.toLang)); }
This is why I cannot call
.then()
on the future because I wouldn't be able to yield the new state from the block of the nested function.Any help is appreciated!