Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flutter: Take action based on snapshot of Future

Tags:

I've come across a problem while trying out Flutter that I can't figure out. The case I'm thinking of has a FutureBuilder widget like below:

 @override
    Widget build(BuildContext context) {
    return new Scaffold(
        appBar: new AppBar(
          title: new Text("Example Page"),
        ),
        body: new FutureBuilder(
            future: _exampleFuture,
            builder: (BuildContext context, AsyncSnapshot<dynamic> snapshot) {
              switch (snapshot.connectionState) {
                case ConnectionState.waiting: return new Center(child: new CircularProgressIndicator(),);
                default:
                  if(snapshot.hasError) {
                    return new Center(child: new Text('Error: ${snapshot.error}'),);
                  }
                  else {
                    return new Center(child: new Text("Result: ${snapshot.data}"),);
                  }
              }
            }
        )
    );
  }

Now let's assume the future is an http call that ends up with a 401 error, indicating that the user is unauthorized. At this point, I'd like the app to erase any token that's stored and redirect to the login page or just rebuild the app. But I can't call a method that does that in the build function, and I don't think didUpdateWidget() is guaranteed to be called, as the future might return it's value before build is called? Maybe I'm approaching this completely wrong, but is there a way to do this in Flutter?

like image 863
Brad Avatar asked Oct 18 '17 00:10

Brad


People also ask

How do you use Future widget in flutter?

In Flutter, the FutureBuilder Widget is used to create widgets based on the latest snapshot of interaction with a Future. It is necessary for Future to be obtained earlier either through a change of state or change in dependencies.

How do you call Future method in flutter?

Sometimes you don't want to turn the function into a Future or mark it async, so the other way to handle a Future is by using the . then function. It takes in a function that will be called with the value type of your Future. It's similar to a Promise in JavaScript without the resolve, reject explicitness.

Why is FutureBuilder called multiple times?

It's meant to represent any widget that triggers rebuilds like, for example, a user scrolling a ListView . The screen is split in two: Top: a StatelessWidget containing a FutureBuilder . It's fed a new Future that resolves to the current date in seconds.

How do you get the Future object in flutter?

get() method returns a Future object: Calling a function that returns a Future, will not block your code, that's why that function is called asynchronous. Instead, it will immediately return a Future object, which is at first uncompleted. Future<T> means that the result of the asynchronous operation will be of type T .


1 Answers

You can check for a statusCode inside your Async method, and use setState to erase the value of the token based on the statusCode value; otherwise, if the connection is authorized, return your desired data. Now, in your FutureBuilder , check if the you snapshot is null to show a SignIn() page instead.

For example, your method that handles the http requests might look something like:

_Request() async {
    var httpClinet = createHttpClient();
    var response = await httpClinet.get(
        url, headers: {'Authorization': "Bearer $_currentUserToken"});
    if (response.statusCode == 200) {
      var myRequest = JSON.decode(response.body);
      var myDesiredData;

      ///TODO: Some data conversions and data extraction
      return myDesiredData;
    }
    else {
      setState(() {
        _currentUserToken = null;
      });
      return null;
    }
}

Then you can have a FutureBuilder like this:

@override
Widget build(BuildContext context) {
  return new FutureBuilder(
      future: _request(),
      builder: (BuildContext context, AsyncSnapshot response) {
        response.hasData==false? new SignIn(): new Scaffold(
          appBar: new AppBar(title: new Text("Future Builder"),),
          body: new Center(
            child: new Text("Build your widgets"),
          ),
        );
      },
   );
}
like image 166
Shady Aziza Avatar answered Oct 13 '22 05:10

Shady Aziza