Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to show a dialog inside a futurebuilder?

Tags:

flutter

dart

I want to show a dialog if I receive an error in a futurebuilder.

If I receiver an error, I want to show a dialog and force the user to click on the button, so that he can be redirected to another page.

The problems seems to be that it is not possible to show a dialog while widget is being built.

FutureBuilder(
      future: ApiService.getPosts(),
      builder: (BuildContext context, AsyncSnapshot snapShot) {
        if (snapShot.connectionState == ConnectionState.done) {
          if (snapShot.data.runtimeType == http.Response) {
            var message =
              json.decode(utf8.decode(snapShot.data.bodyBytes));

    showDialog(
     context: context,
     barrierDismissible: false,
     builder: (context) {
       return AlertDialog(
        content: Text(message),
        actions: <Widget>[
          FlatButton(
            child: Text("Ok"),
            onPressed: () => null",
          )
        ],
      );
    });
  }
     return ListView.separated(
            separatorBuilder: (BuildContext context, int index) {
              return Divider(
                color: Colors.grey,
                height: 1,
              );
            },
            itemBuilder: (BuildContext context, int index) {
              return _buildPostCard(index);
            },
            itemCount: snapShot.data.length,
          );
     return Center(
          child: CircularProgressIndicator(),
        );
      },
    )

If I return the AlertDialog alone, it works. But I need the showDialog because of the barrierDismissible property.

Does any one know if that is possible? Also, is this a good way to handle what I want?

Thanks

UPDATE

For further reference, a friend at work had the solution.

In order to do what I was looking for, I had to decide which future I was going to pass to the futureBuilder.

Future<List<dynamic>> getPostsFuture() async { 
try {
    return await ApiService.getPosts();
  } catch (e) {

     await showDialog(
 context: context,
 barrierDismissible: false,
 builder: (context) {
   return AlertDialog(
    content: Text(message),
    actions: <Widget>[
      FlatButton(
        child: Text("Ok"),
        onPressed: () => null",
      )
    ],
  );
});
  }
}

}

Then in the futureBuilder I would just call

FutureBuilder(
  future: getPostsFuture(),

Thanks

like image 822
Diego Vin Avatar asked Jul 04 '19 22:07

Diego Vin


1 Answers

To avoid setState() or markNeedsBuild() called during build error when using showDialog wrap it into Future.delayed like this:

Future.delayed(Duration.zero, () => showDialog(...));
like image 160
georkings Avatar answered Oct 18 '22 13:10

georkings