Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flutter/Dart: How to make data load on the first tab when launching application?

Tags:

flutter

dart

Brief explanation: I am creating an application that currently has three tabs. Upon loading the application, the data does not load on the first page. It just says "finding specials". When I swipe to the left, the information loads on the second and third tab, and only when I go BACK to the first tab does the information load there.img

Code:

void main() => runApp(MaterialApp(
      title: "Local Hour application",
      debugShowCheckedModeBanner: false,
      home: MyTabs(), //Change to HomePage when wanting first clicking page
    )
);

class MyTabs extends StatefulWidget {
  @override
  MyTabsState createState() => MyTabsState();
}

class MyTabsState extends State<MyTabs> with SingleTickerProviderStateMixin {

  final String url = 'url-info-I-can\'t-disclose'; //API url
  List specials;
  TabController controller;

  @override
  void initState() {
    super.initState();

    controller = TabController(vsync: this, length: 3);

    this.getSpecials().then((jsonSpecials) {
      setState(() {
        specials = jsonSpecials;
      });
    });
  }

  @override
  void dispose() {
    controller.dispose();
    super.dispose();
  }

  Future<List> getSpecials() async {
    var response = await http.get(
        Uri.encodeFull(url + '/specials'),
        headers: {"Accept": "application/json"});
    return jsonDecode(response.body);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        leading: Icon(Icons.dehaze), //there's an "action" option for menus and stuff. "leading" for show
        title: specials == null ? Text("LOCAL HOUR",) : Text("Now with more special",),
        backgroundColor: Colors.green,
        bottom: TabBar(
          controller: controller,
          tabs: [
            Padding(
              padding: const EdgeInsets.all(15.0),
              child: Text("Today", style: TextStyle(fontSize: 15.0),),
            ),
            Padding(
              padding: const EdgeInsets.all(15.0),
              child: Text("Tomorrow", style: TextStyle(fontSize: 15.0),),
            ),
            Padding(
              padding: const EdgeInsets.all(15.0),
              child: Text("Next Day", style: TextStyle(fontSize: 15.0),),
            ),
          ],
        )
      ),
      body: TabBarView(
        controller: controller,
        children: <Widget>[
          SecondPage(specials: specials),
          SecondPage(specials: specials),
          SecondPage(specials: specials),
        ],
      ),
    );
  }

**Current issue: ** first page does not load on launching. Only when switching back and forth between tabs.

**My goal: ** to ensure that the data does load when launching the application and that I do not have to go back and forth just to see the first page.

Please let me know if I need to supply more information.

like image 475
Michael Tolsma Avatar asked Dec 13 '19 14:12

Michael Tolsma


1 Answers

Michael, you should use FutureBuilder to make your future requests instead of requesting it in initState(). Below is how you can implement it. Since i don't have your api, i used a test api to demonstrate.

class MyTabs extends StatefulWidget {
  @override
  MyTabsState createState() => MyTabsState();
}

class MyTabsState extends State<MyTabs> with SingleTickerProviderStateMixin {
  final String url = 'https://jsonplaceholder.typicode.com/posts'; //API url

  List specials;
  TabController controller;

  @override
  void initState() {
    super.initState();

    controller = TabController(vsync: this, length: 3);

//    this.getSpecials().then((jsonSpecials) {
//      setState(() {
//        specials = jsonSpecials;
//      });
//    });
  }

  @override
  void dispose() {
    controller.dispose();
    super.dispose();
  }

  Future<List> getSpecials() async {
    var response = await http.get(Uri.encodeFull(url),
        headers: {"Accept": "application/json"});
    return jsonDecode(response.body);
  }

  @override
  Widget build(BuildContext context) {
    return FutureBuilder(
        future: getSpecials(),
        builder: (context, snapshot) {
          if (snapshot.hasData) {
            print(snapshot.data[0]);
            return MaterialApp(
                home: Scaffold(
              appBar: AppBar(
                  leading: Icon(Icons.dehaze),
                  //there's an "action" option for menus and stuff. "leading" for show
                  title: specials == null
                      ? Text("LOCAL HOUR")
                      : Text("Now with more special"),
                  backgroundColor: Colors.green,
                  bottom: TabBar(
                    controller: controller,
                    tabs: [
                      Padding(
                        padding: const EdgeInsets.all(15.0),
                        child: Text("Today", style: TextStyle(fontSize: 15.0)),
                      ),
                      Padding(
                        padding: const EdgeInsets.all(15.0),
                        child:
                            Text("Tomorrow", style: TextStyle(fontSize: 15.0)),
                      ),
                      Padding(
                        padding: const EdgeInsets.all(15.0),
                        child:
                            Text("Next Day", style: TextStyle(fontSize: 15.0)),
                      ),
                    ],
                  )),
              body: TabBarView(
                controller: controller,
                children: <Widget>[
                  Padding(padding: EdgeInsets.only(top: 10.0),child: Text(snapshot.data[0]["title"], textAlign: TextAlign.center, style: TextStyle(fontSize: 18.0, fontWeight: FontWeight.bold))),
                  Padding(padding: EdgeInsets.only(top: 10.0),child: Text(snapshot.data[1]["title"], textAlign: TextAlign.center, style: TextStyle(fontSize: 18.0, fontWeight: FontWeight.bold))),
                  Padding(padding: EdgeInsets.only(top: 10.0),child: Text(snapshot.data[2]["title"], textAlign: TextAlign.center, style: TextStyle(fontSize: 18.0, fontWeight: FontWeight.bold))),
                ],
              ),
            ));
          } else {
            return Center(child: CircularProgressIndicator());
          }
        });
  }
}

demo

like image 72
Pro Avatar answered Oct 23 '22 23:10

Pro