Mobx Observer not working as expected when using FutureBuilder
So today i managed to implement a workaround for my problem by introducing a class-member holding the items, and react on receiving them by calling itemTracker.updateAmount()
inside an initState()
-method.
class OfferPage extends StatefulWidget {
final Future<List<Offer>> data = ApiService.getOffers();
OfferPageState createState() => OfferPageState();
}
class OfferPageState extends State<OfferPage> {
@override
void initState() {
widget.data.then((offers) => itemTracker.updateAmount(offers.length));
super.initState();
}
// ...
//the new Scaffold body part
body: ListView(
shrinkWrap: true,
padding: const EdgeInsets.all(20.0),
children: <Widget>[
FutureBuilder(
// no longer create a request, but instead use the existing request's future
future: widget.data,
builder: (BuildContext context, AsyncSnapshot snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.none:
case ConnectionState.waiting:
return Center(
child: CircularProgressIndicator(),
);
default:
return _createOfferList(context, snapshot);
}
}),
],
),
The _createOfferList
-method remains exactly the same albeit without the call to updateAmount()
, since this part is now handled inside initState()
.
Paez Rice
Updated on December 13, 2022Comments
-
Paez Rice over 1 year
When trying to create a Listview of items inside the body of a Scaffold, I am unable to update the displaying of the amount of items in that list in another place (Appbar) with mobx (version: 0.3.5) and flutter_mobx (version: 0.3.0+1).
I already tried to solve this with the Provider package (3.0.0+1), but this didn't work out as well, so I guess I am missing something about the nature of FutureBuilder and Flutter's build-process.
// the mobx-store ItemTracker itemTracker = ItemTracker(); class StartPage extends StatefulWidget { StartPageState createState() => StartPageState(); } class StartPageState extends State<StartPage> { Widget build(BuildContext context) { return SafeArea( child: Scaffold( appBar: AppBar( // this Observer doesn't update leading: Observer( builder: (_) => Text('Items: ' + itemTracker.amount.toString())), title: Text('MyApp', style: TextStyle( color: Colors.deepPurpleAccent[50], fontSize: 16, fontWeight: FontWeight.bold, )), centerTitle: true, ), body: ListView( shrinkWrap: true, padding: const EdgeInsets.all(20.0), children: <Widget>[ FutureBuilder( future: ApiService.getOffers(), builder: (BuildContext context, AsyncSnapshot<List<Offer>> snapshot) { switch (snapshot.connectionState) { case ConnectionState.none: case ConnectionState.waiting: return Center( child: CircularProgressIndicator(), ); default: return snapshot.hasError ? Text('Error: ${snapshot.error}') : _createOfferList(context, snapshot); } }), ], ), ), ); }
Widget _createOfferList(BuildContext context, AsyncSnapshot snapshot) { // after receiving the response, the amount of items should get written to // itemTracker.amount - the Observer-part should be rerendered, but it won't itemTracker.updateAmount(snapshot.data.length); print(snapshot.data.length.toString()); return ListView.builder( itemCount: snapshot.data.length, shrinkWrap: true, primary: false, itemBuilder: (BuildContext context, int index) { return Card( color: Colors.lightBlue[50], child: ListTile( leading: Image.asset(snapshot.data[index].image), title: Text(snapshot.data[index].name), subtitle: Text(snapshot.data[index].description ?? ''), isThreeLine: true, trailing: Padding( padding: EdgeInsets.only(top: 8.0, right: 4.0), child: Icon( Icons.explore, color: Colors.green[200], size: 30, ), ), onTap: () => Navigator.push( context, MaterialPageRoute( builder: (context) => OfferDetailPage(snapshot.data[index]))), )); }); } }
so the upper part of the code fetches the items from
ApiService.getOffers
and then calls the_createOfferList
to build the Listview. Inside this method, theitemTracker
-instance's mobx-observableamount
gets updated by the mobx-actionupdateAmount(int newValue)
with the length of the snapshot's data-list.
In theScaffold
above, I'm then using anObserver
to track and display the amount of items.
Aside from the amount not getting updated, the App works as expected and the List gets rendered. If I navigate forth and back in the app, the amount of list-items gets displayed correctly, but it never happens on the initial page-load.edit: just as a side-note: I didn't show off the
ItemTracker
class-definition and the corresponding generated class, since all it does is use an observable-annotation for theamount
-member and an action-annotation for the method that just takes an int-parameter and writes it tothis.amount
.