1

I need to do the widget with Flutter like "N users watch on it now", where N comes from the backend, and I need to update it every 5 seconds if the widget is visible.

I tried a few approaches with Future.delayed and Timer like this ones:

            _timer = Timer(
              const Duration(seconds: 5),
              () {
                if (isCounterVisible) {
                  // load data 
                }
              },
            );

  @override
  void dispose() async {
    if (_timer != null) {
      _timer!.cancel();
      _timer = null;
    }
  }

But facing an issue that requests still sending after I go away from this screen, and unit tests failed for the reason A Timer is still pending even after the widget tree was disposed

Also, I have problems with determining is widget visible or not. I used library visibility_detector but seems it does not work with modal windows - the listener does not trigger when the modal window showed.

Md. Yeasin Sheikh
  • 54,221
  • 7
  • 29
  • 56
anber
  • 3,463
  • 6
  • 39
  • 68

2 Answers2

2

Timer.periodic will do the job, Also you can use cancelable future. You are missing super.dispose();.

Timer? timer;

void initTimer() {
  if (timer != null && timer!.isActive) return;

  timer = Timer.periodic(const Duration(seconds: 5), (timer) {
    //job
    setState(() {});
  });
}

@override
void dispose() {
  timer?.cancel();
  super.dispose();
}

Now use initTimer() to start woker.

Md. Yeasin Sheikh
  • 54,221
  • 7
  • 29
  • 56
1

You could use a RiverPod StreamProvider.autoDispose wrapped around a Timer.periodic to wake up a Consumer Widget at regular intervals. It will automatically go away when no longer referenced.

Randal Schwartz
  • 39,428
  • 4
  • 43
  • 70