2

Basically I use this syntax to use a FutureBuilder:

  retur FutureBuilder(
        future: future,// http request
        builder: (context, AsyncSnapshot<dynamic> snapshot) {
          if (snapshot.connectionState == ConnectionState.done) {
            Text("success done");
          }
          if (snapshot.hasData) {
            if (snapshot.data["error"] == "111") {
             rerurn Text("not access server")
            }
            if (snapshot.data["data"]["ok"] == false) {

              return Text("problem");
            }
            return Container();
          } else {
            return Text("Loading");
          }
        });

Every time I want to make a web request, I have to write all this code again.

I want to optimize this, so I'm thinking of converting the above code into a method where I simply pass a future (http request) parameter and return what my FutureBuilder would return.

I'm trying something like this:

Future generateFutureBuilder(Future<dynamic> future, Widget widget) {
   //widget is a Widget to show when it finishes
  FutureBuilder(
      future: future,// http request
      builder: (context, AsyncSnapshot<dynamic> snapshot) {
        if (snapshot.connectionState == ConnectionState.done) {
          Text("success done");
        }
        if (snapshot.hasData) {
          if (snapshot.data["error"] == "111") {
          }
          if (snapshot.data["data"]["ok"] == false) {

            return Text("problem");
          }
          return widget;
        } else {
          return Text("Loading");
        }
      });
}
generateFutureBuilder(http.get(myurl), Container(child:Text("finished")))

but it doesn't behave like it normally does.

What I can do?

yavg
  • 2,761
  • 7
  • 45
  • 115

1 Answers1

0

Although using a method to abstract widgets is OK, it typically is better to create a class that extends StatelessWidget. To fix your current method, you need to make it return FutureBuilder, not Future, and actually add a return statement. Another good change would be changing the use of dynamics to generics for better type safety.

But another plausible solution that will give you a little more control when building your widget is to not abstract away the FutureBuilder itself, but just the snapshot it gives you. Example:

/// Returns a widget to show if needed (either error or loading), or null if success
Widget getFutureSnapshotWidget(AsyncSnapshot snapshot) {
  // if has data that is ok:
  //   return null;
  // else:
  //   return either an error as a Text or a CircularProgressIndicator
}

Then you can call the following in your builder of FutureBuilder:

final widgetToShow = getFutureSnapshotWidget(snapshot);
if (widgetToShow != null) {
  return widgetToShow;
}

// Show regular widget here

Gregory Conrad
  • 1,324
  • 11
  • 19
  • Could you explain further the part "although ...is OK, it is better..."? – Antonin GAVREL Jun 07 '20 at 04:48
  • 1
    See [this answer](https://stackoverflow.com/a/53234826/10003008); it explains it very well. In this case, they would want a reusable widget for FutureBuilder, so it would be better to subclass StatelessWidget. – Gregory Conrad Jun 08 '20 at 02:04