0

I want to use the BottomNavigationBar with multiple tabs, each of them should preserve its state. As each tab is containing a list of items based on a JSON parsing from the web, I have to deal with multiple futures.

At the moment I have the following approach: BottomNavigationBar with IndexedStack, the index looks like this

static final List<Widget> _pages = <Widget>[
FutureBuilder<List<Photo>>(
  future: fetchPhotos(http.Client()),
  builder: (context, snapshot) {
    if (snapshot.hasError) {
      return Center(
        child: Text('Error on Tab 1'),
      );
    } else if (snapshot.hasData) {
      return PhotosList(photos: snapshot.data!);
    } else {
      return Center(
        child: CircularProgressIndicator(color: Colors.orange),
      );
    }
  },
),
FutureBuilder<List<Onboardvideo>>(
  future: fetchOnboardvideos(http.Client()),
  builder: (context, vidsnapshot) {
    if (vidsnapshot.hasError) {
      return Center(
        child: Text('Error on Tab 2'),
      );
    } else if (vidsnapshot.hasData) {
      return OnboardvideosList(onboardvideos: vidsnapshot.data!);
    } else {
      return Center(
        child: CircularProgressIndicator(color: Colors.orange),
      );
    }
  },
),
const Padding(
    padding: EdgeInsets.symmetric(vertical: 15),
    child: Text(
        "Work in progress"
        , style: optionStyle)),

];

What confuses me here is that my code is sometimes executed without any issues and sometimes I get the "Error on Tab 2" message. Tab 1 and 3 are always loaded without issues.

I start to suspect that the IndexedStack does not work well with two FutureBuilders in a row , so that it works sometimes and sometimes not. Maybe because the app is not waiting for both futures.

I did some research and it seems to be possible to load both futures within one FutureBuilder. But I think that is the wrong approach in my case. The best would be to preserve the state just like within an IndexedStack, but to load each page seperately with its own FutureBuilder as soon as the according button on the BottomNavigationBar is tapped. The app would be more efficient then as well and I would save some API quotas on tab 2.

I have found some articles telling to use AutomaticKeepAliveClientMixin, but the next article says I should never do this but use IndexedStack as it is much better.

So I am definitely confused now how I can archive my necessary combination. I am quite new to flutter so it would be great if you could share an example of your recommendation. Thanks!

cornemrc
  • 45
  • 6
  • and what do you see if you `print(vidsnapshot.error)`? – pskink Jan 29 '23 at 10:01
  • I just get type 'Null' is not a subtype of type 'String' in the console. – cornemrc Jan 29 '23 at 10:24
  • I have just switched to this approach here: https://stackoverflow.com/a/64057210/12297359 Now the tab2 future is loaded not during the start but the issue remains. Sometimes it is working without an issue, sometimes vidsnapshot has an error I can not find ... – cornemrc Jan 29 '23 at 10:27
  • `print` this: https://api.flutter.dev/flutter/widgets/AsyncSnapshot/stackTrace.html – pskink Jan 29 '23 at 11:02
  • Thanks, I have found the issue. I switched to AutomaticKeepAliveClientMixin instead of IndexedStack but the issue was not resolved. Then I found that the problem was related to my JSON model, as the JSON is sometimes responding with a particular field of type string and sometimes not. – cornemrc Feb 14 '23 at 16:01

0 Answers0