Home > Mobile >  How to refresh a widget with stream builder in flutter
How to refresh a widget with stream builder in flutter

Time:09-29

I am trying to show data from the text file as per the data stored in shared preference i have another screen to save data in the text file i have a stream builder earlier it was future builder So i am trying to refresh the screen when coming back from second screen i tried to call a method when pop the method is getting called in the viewmodel calss of provider but the streambuilder is not getting updated this is the code

to fetch data

Future<List<String>> fetchdata() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
String? category = prefs.getString('category');
if (category != null) {
  lines = await locator<JsonAPI>().fetchquotes(category);
} else {
  lines = await locator<JsonAPI>().fetchquotes('quotes');
}
// data = lines as Future<List<String>>;
notifyListeners();
return lines;
}

stream builder

         var quotesdata = Provider.of<HomeViewModel>(context, listen: false);

 StreamBuilder(
              stream: quotesdata.fetchdata().asStream(),
              builder: (context, AsyncSnapshot snapshot) {
                if (snapshot.hasData) {
                  List<String> lines = quotesdata.lines;
                  // List<String>? lines = snapshot.data as List<String>?;
                  return ScreenShotWidget(
                    homeViewModel: quotesdata,
                    list: lines,
                  );
                } else {
                  return Container();
                }
              }),

method that i call when pop

function(data) {
category = data.toString();
fetchdata();
notifyListeners();
setState() {}
}

any idea how to update the screen

CodePudding user response:

Every time your widget rebuilds, you get a new stream. This is a mistake. You should obtain the stream only once (for example, in initState)

@override
void initState() {
  _stream = quotesdata.fetchdata().asStream();
}

and use that stream variable with StreamBuilder

 StreamBuilder(
   stream: _stream,

Later, when you want to update the stream, you can do

setState(() {
  _stream = quotesdata.fetchdata().asStream();
}) 

to change the stream and force a refresh.

Please go over your code and change all such usages

 StreamBuilder(
   stream: quotesdata.fetchdata().asStream(),

to this kind of usage.

 StreamBuilder(
   stream: _stream,

Otherwise you may get a high backend bill someday. Right now every screen refresh does a new query to the backend.

  • Related