Reload data when using FutureBuilder

what i did an it worked for me, is to call the future function again in setState(). in your example it will looks like this.

first you assign your _getData() future function to a variable (_myData) with the same return type, after that, you can override it's value in setState() that will rebuild the UI and therefor run the future again.

in code it will looks like this.(from you example):

class _MyHomePageState extends State<MyHomePage> {

Future<List<String>>  _myData = _getData(); //<== (1) here is your Future

@override
      Widget build(BuildContext context) {
        var futureBuilder = new FutureBuilder(
          future: _myData; //<== (2) here you provide the variable (as a future)
          builder: (BuildContext context, AsyncSnapshot snapshot) {
            switch (snapshot.connectionState) {
              case ConnectionState.none:
              case ConnectionState.waiting:
                return new Text('loading...');
              default:
                if (snapshot.hasError)
                  return Column(
                  children: [
                    Icon(Icons.error),
                    Text('Failed to fetch data.'),
                    RaisedButton(
                      child: Text('RETRY'), 
                      onPressed: (){
                        setState(){
                            _myData = _getData(); //<== (3) that will trigger the UI to rebuild an run the Future again
                        }
                      },
                    ),
                  ],
                );
                else
                  return createListView(context, snapshot);
            }
          },
        );

        return new Scaffold(
          appBar: new AppBar(
            title: new Text("Home Page"),
          ),
          body: futureBuilder,
        );
      }

I did a deep dive into this and it's not that difficult. The builder is properly rebuilt on changing the future (if you trigger the change with setState). Problem is, the hasData and hasError aren't reset until the response is back. But we can use connectionState instead.

final builder = FutureBuilder(
    future: _future,
    builder: (context, snapshot) {
      if (snapshot.connectionState != ConnectionState.done) {
        return _buildLoader();
      }
      if (snapshot.hasError) {
        return _buildError();
      }
      if (snapshot.hasData) {
        return _buildDataView();
      }     
      return _buildNoData();
});

Here's a post on the issue and a linked repo showing the issue and solution: https://www.greycastle.se/reloading-future-with-flutter-futurebuilder/


Widget createListView(BuildContext context, AsyncSnapshot snapshot) {
  RaisedButton button = RaisedButton(
    onPressed: () {
      setState(() {});
    },
    child: Text('Refresh'),
  );
  //.. here create widget with snapshot data and with necessary button
}