1

I have this Future and my code template like this:

Future getDevices() async {
stream.listen();
Timer.periodic(Duration(seconds:5), (timer) {
  POST TO SERVER.then((value){
    return Future.value(value);
  });
});
}

I'm Listening to a Stream to scan for beacon devices. I fill the yield named "beacons" in the Listen function of this Stream. With Timer.periodic, I control the yield named "beacons" and perform POST operation. I want to return Future.value on "then" of this POST operation. But Future returns null without waiting for the result of POST operation.

I tried Completer like this:

Future getDevices() async {
final completer = Completer();
stream.listen();
Timer.periodic(Duration(seconds:5), (timer) {
  POST TO SERVER.then((value){
    return completer.complete(value);
  });
});
return completer.future;
}

but this time I also got this error: "Unhandled Exception: Bad state: Future already completed"

EDIT: I try to use Stream.asyncMap but same result when i did it.

Stream myStream = Stream.periodic(Duration(seconds: 5), (timer) async {
      beacons.removeWhere((key, value) =>
          DateTime.now().difference(value['lastUpdate']).inSeconds > 6);
      if (beacons.isNotEmpty) {
        bool processResult = false;
        beacons.forEach((key, value) async {
          if (int.parse(value['onlyEnterance'].toString()) == 1 &&
              double.parse(value['distance'].toString()) <
                  double.parse(value['minDistance'].toString())) {
            await userRepo
                .createPayrollTracking(context, forEnter, value['dbId'])
                .then((value) {
              processResult = value;
              if (value == true) {
                stopMonitoring();
              }
            });
            return await Future.value(processResult);
          }
        });
      }
    }).asyncMap((event) async => await event);
Baran Gungor
  • 205
  • 2
  • 11
  • 1
    do not use `Timer.periodic` if you use `Stream`s - instead use `Stream.periodic` - it will yield new value on periodic basis – pskink Dec 29 '21 at 16:05
  • The `Timer.periodic` usage does not make sense since it takes a `void Function(Timer)` as the callback. Returning a value from the callback is useless, and if the callback does asynchronous operations, there is no way to wait for them to complete. It's also unclear how you intend for `getDevices` to work: when is the returned `Future` supposed to be considered complete? – jamesdlin Dec 29 '21 at 18:37
  • @pskink i revised to Stream.periodic and used in StreamBuilder this stream but the StreamBuilder send null as snapshot.data from Stream.periodic . I need know how can i run async function and await for the function in Stream.periodic . – Baran Gungor Dec 30 '21 at 09:18
  • see [Stream.asyncMap](https://api.flutter.dev/flutter/dart-async/Stream/asyncMap.html) – pskink Dec 30 '21 at 09:19
  • @pskink i'll edit question please wait. – Baran Gungor Dec 30 '21 at 09:21
  • 1
    `beacons.forEach((key, value) async {` - see https://stackoverflow.com/questions/63719374/how-to-wait-for-foreach-to-complete-with-asynchronous-callbacks/63719805#63719805, also it is tricky to use async in `Stream.periodic` constructor (`(timer) async {...`), - better get your data inside `asyncMap` – pskink Dec 30 '21 at 09:41
  • 1
    something like: `Stream.periodic(Duration(seconds: 5)).asyncMap((_) async {... return processResult;});` – pskink Dec 30 '21 at 09:54
  • Thank you very much for your help. I am grateful to you @pskink and jamesdlin – Baran Gungor Dec 30 '21 at 10:03

0 Answers0