escamoteur/watch_it

watchStream keeps getting triggered

Closed this issue ยท 6 comments

I would like to implement an example of how to use watchStream as per documentation.

It seams like the watchStream gets triggered repetitively, and I'm not sure what's causing that.

This is how it looks like after implementation:

Screen_Recording_20240808-105427.mp4

You may check the implementation in this branch. and you may also find the changes in this Pull Request.

Please help look into this issue and let me know if im doing anything wrong in the implementation.

Thank you.

I mean the only thing that I don't understand is that in your linked branch you have a delay of 20s which seems not to be the case in the video.
Not sure why you think it does not behave as it should?
A better example would probably using a StreamController<List in the manager and then build the full list in the UI after watchStream

Thanks for replying @escamoteur.

The stream, i set, is supposed to emit events every 20 seconds. But, as you can see in video, the rebuilds happen faster than that (widget rebuilds every few milliseconds).

I have tested the source stream watchWeatherInCities() without use of watchStream, and the events are emitted as expected (every 20 seconds)

But when I use watchStream to subscribe to the stream, I get the behaviour in video. I was suspecting that watchStream is re-subscribing to the stream every time the widget is rebuilt, but i think that is not the case after looking at the watchStream documentation:

/// When you call [watchStream] a second time on the same Stream it will
/// return the last received data but not subscribe another time.

I have tried using StreamController at source of the stream as you've suggested, and watchStream is able to subscribe and rebuild widget only once every 20 seconds (expected behaviour ๐Ÿ‘ ).

Real Scenario

In my real scenario, I am using Drift for Database and getting data as follow:

Stream<List<WeatherEntry>> watchWeatherInCities() => select(tableName).watch();

Then in the widget, I subscribe to the stream as follow:

class WatchStreamExample extends WatchingWidget {
  const WatchStreamExample({super.key});

  @override
  Widget build(BuildContext context) {
  
    // subscribe to stream of weather entries from DB
    final List<WeatherEntry>? weatherEntries =
        watchStream<WeatherController, List<WeatherEntry>?>(
      (controller) => controller.watchWeatherInCities(),
    ).data;

    print('++++> new list of entries: $weatherEntries');

    return Scaffold(/*more logic*/);
  }
}

Question

Does watch_it package allow subscribing to the stream directly as in the example above? or do I still need to use StreamController or StreamSubscription to manage the stream

Thank you for looking into my code @escamoteur.

Exactly, I think what you mentioned here is the case I had:

And I suspect that although Dart treats the return value as a Stream, if you call it multiple times the returned stream instance won't have the same object id so watch_it doesn't know it is the same stream and so subscribes again.

Assigning value returned from the source stream to a property that is pre-defined in the controller class, and watching that property resolved the issue. Incorporating a StreamController is an alternative to achieve same expected behaviour.

Thanks Again.