2017-10-18 3 views
1

J'ai rencontré un problème en essayant Flutter que je ne peux pas comprendre. Le cas je pense a un widget FutureBuilder comme ci-dessous:Flutter: Prendre une action basée sur l'instantané de l'avenir

@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}"),); 
        } 
       } 
      } 
     ) 
    ); 
    } 

Maintenant, supposons que l'avenir est un appel http qui se termine avec une erreur 401, indiquant que l'utilisateur est non autorisé. À ce stade, j'aimerais que l'application efface tout jeton stocké et redirigé vers la page de connexion ou reconstruise simplement l'application. Mais je ne peux pas appeler une méthode qui fait cela dans la fonction de construction, et je ne pense pas que didUpdateWidget() est garanti d'être appelé, comme l'avenir pourrait retourner sa valeur avant que build est appelé? Peut-être que j'aborde complètement ce problème, mais y a-t-il un moyen de le faire dans Flutter?

+0

Je peaufiné mon code un peu. – aziza

Répondre

3

Vous pouvez vérifier un statusCode dans votre méthode Async et utiliser setState pour effacer la valeur du jeton en fonction de la valeur statusCode; sinon, si la connexion est autorisée, renvoyez les données souhaitées. Maintenant, dans votre FutureBuilder, vérifiez si l'instantané de vous est null pour afficher une page SignIn() à la place.

Par exemple, votre méthode qui gère les requêtes http pourraient ressembler à:

_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; 

     } 
} 

Ensuite, vous pouvez avoir un FutureBuilder comme ceci:

@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"), 
      ), 
     ); 
    } 
    ); 
} 
+1

Merci aziza. Cela a du sens pour moi. Je suppose que j'ai obtenu la valeur future dans 'initState()', car j'ai mis en cache les réponses et cela semble éliminer tout scintillement de l'écran si je retourne à la page et que le futur est récupéré du cache. Peut-être que je dois revenir à l'appel d'une méthode dans 'FutureBuilder' et repenser un peu le reste de la logique. – Brad

+0

Heureux que cela a aidé, et j'espère que vous finirez par y arriver. – aziza