6

I am retrieving data from a REST API using a stream, but when the data updates in the database the stream does not refresh the data in the app.

StreamController _productsController = new StreamController();
...         
//products is a list that contains the data
_productsController.add(products);
...
body: Container(
        child: StreamBuilder(
            stream: _productsController.stream,
            builder: (BuildContext context, AsyncSnapshot snapshot) {...}

I saw a solution proposing to periodically re-load the data from the API, for example each 1 second.

Timer.periodic(Duration(seconds: 1), (_) => loadDetails());

Source: Stream for API coming from PHP in Flutter (Not Firebase)

I do not think it is an efficient approach. In my app for example, I want to integrate the data changes without re-loading the data.

Is there an efficient way to make the stream reflects data changes in the app without reloading data?

EddyG
  • 2,051
  • 3
  • 22
  • 46

1 Answers1

16

You can implement your own stream with dart as shown in the docs

With this, you will also need a delay and you will be making calls to the API periodically, but I guess that's the way to go if your API does not send any message without calling it first.

Stream<Product> productsStream() async* {
  while (true) {
    await Future.delayed(Duration(milliseconds: 500));
    Product someProduct = getProductFromAPI();
    yield someProduct;
  }
}

A little explanation of the code:

  • You need a loop to call the API periodically. Don't worry about infinite loops, since the stream will only be used while the StreamBuild that calls it is built.
  • The yield keyword is like the return when using streams

Then, to use it, just implement a StreamBuilder calling the Stream you just created:

StreamBuilder(
    stream: productsStream(),
    builder: (BuildContext context, AsyncSnapshot<Product> snapshot) {...}
)
jsgalarraga
  • 425
  • 6
  • 13
  • Will it work when app is death ?, means app is installed in phone but not using or running on background – Mukta Dec 05 '20 at 00:44
  • @Mukta no, streams implemented this way only update while the widget is built. I'm not sure if making some changes you can make it update while running on background – jsgalarraga Dec 06 '20 at 11:48
  • @jsgalarraga what if I am calling the `Stream` in `initState` of a StatefulWidget. Will it run in background? – MohitC May 18 '22 at 19:39
  • @jsgalarraga This was working fine for a couple of seconds(like 40-45 seconds) and updating the list, but after that circular loader comes and loader seems to load infinitely. – KJEjava48 May 26 '23 at 07:21