Home > front end >  How to await a listener being called and return a Future value
How to await a listener being called and return a Future value

Time:02-01

I have a Future function which adds a listener to a ValueNotifier. How can I return a value that I retrieve when the listener is called?

  Map<String,ValueNotifier<String>> _data = {};

  Future<String> getAnswer(String text) async {
    if (_data["answer"] == null || _data["answer"]!.value.isEmpty) {
      _data["answer"] = ValueNotifier<String>("");

      _data["answer"]!.addListener(() {
        if (_data["answer"]!.value.isNotEmpty) {
          // somehow return _data["answer"]!.value
        } else {
          // continue waiting for next listener call
        }
      });

    } else {
      return _data["answer"]!.value;
    }

    return await //not sure what to put here.
  }

CodePudding user response:

Seems like you always want to use the value of _data['answer'] as soon as it gets updated. In this case you should try using Riverpod library: https://pub.dev/packages/flutter_riverpod This library will help you in watching a notifier and then rebuild stateful widgets when the data is updated.

CodePudding user response:

Ok I found a solution that works in this case is to use Completer() as follows:

  Map<String,ValueNotifier<String>> _data = {};

  Future<String> getAnswer(String text) async {
    var completer = Completer<String>();
    if (_data["answer"] == null || _data["answer"]!.value.isEmpty) {
      _data["answer"] = ValueNotifier<String>("");

      _data["answer"]!.addListener(() {
        if (_data["answer"]!.value.isNotEmpty) {
          completer.complete(_data["answer"]!.value);
          _data["answer"]!.dispose();
        }
      });

    } else {
      return _data["answer"]!.value;
    }

    return completer.future;
  }
  •  Tags:  
  • Related