iKreateCode
iKreateCode

Reputation: 209

flutter how to use future async method in init state

When the screen loads i want the init state to fill the List with Future<List> that is passed through the stateful widget. However since its a future, my method will crash and not work.

My code

  @override
  void initState() async {
    FutureBuilder(
      future: widget.imageList,
      builder: (context, snapshot) {
        switch (snapshot.connectionState) {
          case ConnectionState.none:
            print('NONE');
            break;
          case ConnectionState.active:
          case ConnectionState.waiting:
            print("WAITING");
            break;
          case ConnectionState.done:
            print("DONE");
            setState(() {
              imgList = widget.imageList as List<String>;
            });
            break;
        }
      },
    );
    super.initState();
  }

Error Produced


════════ Exception caught by widgets library ═══════════════════════════════════
_BottomSheetWidgetState.initState() returned a Future.
The relevant error-causing widget was
    MaterialApp 

Stateful widget where the list is passed through

List<String> imgList = List<String>();

class BottomSheetWidget extends StatefulWidget {
  BottomSheetWidget({Key key, this.name, this.imageList}) : super(key: key);

  String name;
  Future<List<String>> imageList;

Whole edited code:

List<String> imgList = List<String>();

class BottomSheetWidget extends StatefulWidget {
  BottomSheetWidget({Key key, this.name, this.imageList}) : super(key: key);

  String name;
  Future<List<String>> imageList;

  @override
  _BottomSheetWidgetState createState() => _BottomSheetWidgetState();
}

class _BottomSheetWidgetState extends State<BottomSheetWidget> {
  int _current = 0;

  final List<Widget> imageSliders = imgList
      .map((item) => Container(
            child: Container(
              margin: EdgeInsets.all(5.0),
              child: ClipRRect(
                  borderRadius: BorderRadius.all(Radius.circular(5.0)),
                  child: Stack(
                    children: <Widget>[
                      Image.network(item,
                          fit: BoxFit.cover, height: 1000.0, width: 1000.0),
                      Positioned(
                        bottom: 0.0,
                        left: 0.0,
                        right: 0.0,
                        child: Container(
                          decoration: BoxDecoration(
                            gradient: LinearGradient(
                              colors: [
                                Color.fromARGB(200, 0, 0, 0),
                                Color.fromARGB(0, 0, 0, 0)
                              ],
                              begin: Alignment.bottomCenter,
                              end: Alignment.topCenter,
                            ),
                          ),
                        ),
                      ),
                    ],
                  )),
            ),
          ))
      .toList();

  @override
  Widget build(BuildContext context) {
    return FutureBuilder(
      future: widget.imageList,
      builder: (context, snapshot) {
        switch (snapshot.connectionState) {
          case ConnectionState.none:
            print('NONE');
            break;
          case ConnectionState.active:
          case ConnectionState.waiting:
            print("WAITING");
            break;
          case ConnectionState.done:
            print("DONNE");
            setState(() async {
                imgList = snapshot.data as List<String>;

            });

            return Container(
              decoration: BoxDecoration(
                color: Colors.red,
                borderRadius: BorderRadius.circular(25),
              ),
              height: MediaQuery.of(context).size.height * 0.85,
              width: MediaQuery.of(context).size.width,
              child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                mainAxisSize: MainAxisSize.max,
                children: <Widget>[
                  Padding(
                    padding: EdgeInsets.symmetric(horizontal: 15),
                    child: Column(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      mainAxisAlignment: MainAxisAlignment.end,
                      children: <Widget>[
                        CarouselSlider(
                          items: imageSliders,
                          options: CarouselOptions(
                              enlargeCenterPage: true,
                              enlargeStrategy: CenterPageEnlargeStrategy.height,
                              height: MediaQuery.of(context).size.height - 500,
                              aspectRatio: 2.0,
                              onPageChanged: (index, reason) {
                                setState(() {
                                  _current = index;
                                });
                              }),
                        ),
                        Row(
                          mainAxisAlignment: MainAxisAlignment.center,
                          children: imgList.map((url) {
                            int index = imgList.indexOf(url);
                            return Container(
                              width: 8.0,
                              height: 8.0,
                              margin: EdgeInsets.symmetric(
                                  vertical: 10.0, horizontal: 2.0),
                              decoration: BoxDecoration(
                                shape: BoxShape.circle,
                                color: _current == index
                                    ? Color.fromRGBO(0, 0, 0, 0.9)
                                    : Color.fromRGBO(0, 0, 0, 0.4),
                              ),
                            );
                          }).toList(),
                        ),
                        Text(widget.name,
                            style: TextStyle(
                                fontSize: 30,
                                color: Colors.white,
                                fontWeight: FontWeight.bold)),
                        Text("United Kingdom",
                            style: TextStyle(
                              fontSize: 18,
                              color: Colors.white,
                            )),
                      ],
                    ),
                  )
                ],
              ),
            );
            break;
        }
      },
    );
  }
}

New error from console:

flutter: WAITING

════════ Exception caught by widgets library ═══════════════════════════════════
A build function returned null.
The relevant error-causing widget was
    FutureBuilder<List<String>> 
lib/common_widget/bottom_sheet.dart:54
════════════════════════════════════════════════════════════════════════════════
flutter: DONNE

════════ Exception caught by widgets library ═══════════════════════════════════
setState() callback argument returned a Future.
The relevant error-causing widget was
    FutureBuilder<List<String>> 
lib/common_widget/bottom_sheet.dart:54
════════════════════════════════════════════════════════════════════════════════

Upvotes: 2

Views: 10126

Answers (1)

tnc1997
tnc1997

Reputation: 1962

The initState method is synchronous by design. Rather than creating the FutureBuilder widget in the initState method, you could return the FutureBuilder widget in the overridden build method. Feel free to take a look at the documentation for the FutureBuilder widget here for an example of how this could work.

It looks like there is also an issue with the code in the setState callback function. You probably want to replace imgList = widget.imageList as List<String>; with imgList = snapshot.data as List<String>; in order to use the data from the completed future.

It looks like there is also an issue with the build method not returning a widget in all the cases. I have taken your updated code sample and modified it as below:

import 'package:flutter/material.dart';

class BottomSheetWidget extends StatefulWidget {
  BottomSheetWidget({Key key, this.name, this.imageList}) : super(key: key);

  final String name;

  final Future<List<String>> imageList;

  @override
  _BottomSheetWidgetState createState() => _BottomSheetWidgetState();
}

class _BottomSheetWidgetState extends State<BottomSheetWidget> {
  int _current = 0;

  @override
  Widget build(BuildContext context) {
    return FutureBuilder<List<String>>(
      future: widget.imageList,
      builder: (context, snapshot) {
        if (snapshot.connectionState == ConnectionState.done) {
          final imgList = snapshot.data;

          return Container(
            decoration: BoxDecoration(
              color: Colors.red,
              borderRadius: BorderRadius.circular(25),
            ),
            height: MediaQuery.of(context).size.height * 0.85,
            width: MediaQuery.of(context).size.width,
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              mainAxisSize: MainAxisSize.max,
              children: <Widget>[
                Padding(
                  padding: EdgeInsets.symmetric(horizontal: 15),
                  child: Column(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    mainAxisAlignment: MainAxisAlignment.end,
                    children: <Widget>[
                      CarouselSlider(
                        items: imgList.map(
                          (item) {
                            return Container(
                              child: Container(
                                margin: EdgeInsets.all(5.0),
                                child: ClipRRect(
                                  borderRadius:
                                      BorderRadius.all(Radius.circular(5.0)),
                                  child: Stack(
                                    children: <Widget>[
                                      Image.network(
                                        item,
                                        fit: BoxFit.cover,
                                        height: 1000.0,
                                        width: 1000.0,
                                      ),
                                      Positioned(
                                        bottom: 0.0,
                                        left: 0.0,
                                        right: 0.0,
                                        child: Container(
                                          decoration: BoxDecoration(
                                            gradient: LinearGradient(
                                              colors: [
                                                Color.fromARGB(200, 0, 0, 0),
                                                Color.fromARGB(0, 0, 0, 0)
                                              ],
                                              begin: Alignment.bottomCenter,
                                              end: Alignment.topCenter,
                                            ),
                                          ),
                                        ),
                                      ),
                                    ],
                                  ),
                                ),
                              ),
                            );
                          },
                        ).toList(),
                        options: CarouselOptions(
                          enlargeCenterPage: true,
                          enlargeStrategy: CenterPageEnlargeStrategy.height,
                          height: MediaQuery.of(context).size.height - 500,
                          aspectRatio: 2.0,
                          onPageChanged: (index, reason) {
                            setState(() {
                              _current = index;
                            });
                          },
                        ),
                      ),
                      Row(
                        mainAxisAlignment: MainAxisAlignment.center,
                        children: imgList.map((url) {
                          return Container(
                            width: 8.0,
                            height: 8.0,
                            margin: EdgeInsets.symmetric(
                                vertical: 10.0, horizontal: 2.0),
                            decoration: BoxDecoration(
                              shape: BoxShape.circle,
                              color: _current == imgList.indexOf(url)
                                  ? Color.fromRGBO(0, 0, 0, 0.9)
                                  : Color.fromRGBO(0, 0, 0, 0.4),
                            ),
                          );
                        }).toList(),
                      ),
                      Text(
                        widget.name,
                        style: TextStyle(
                          fontSize: 30,
                          color: Colors.white,
                          fontWeight: FontWeight.bold,
                        ),
                      ),
                      Text(
                        "United Kingdom",
                        style: TextStyle(
                          fontSize: 18,
                          color: Colors.white,
                        ),
                      ),
                    ],
                  ),
                )
              ],
            ),
          );
        } else {
          return CircularProgressIndicator();
        }
      },
    );
  }
}

Upvotes: 4

Related Questions