Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flutter Programmatically trigger FutureBuilder

Tags:

flutter

dart

Let's say I have something like this:

return FutureBuilder(
  future: _loadingDeals,
  builder: (BuildContext context, AsyncSnapshot snapshot) {
    return RefreshIndicator(
      onRefresh: _handleRefresh,
        ...
    )
  }
 )

In the _handleRefresh method, I want to programmatically trigger the re-run of the FutureBuilder.

Is there such a thing?

The use case:

When a user pulls down the refreshIndicator, then the _handleRefresh simply makes the FutureBuilder rerun itself.

Edit:

Full code snippet end to end, without the refreshing part. I've switched to using the StreamBuilder, how will the refreshIndicator part fit in all of it?

class DealList extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => new _DealList();
}

class _DealList extends State<DealList> with AutomaticKeepAliveClientMixin {
  // prevents refreshing of tab when switch to
  // Why? https://stackoverflow.com/q/51224420/1757321
  bool get wantKeepAlive => true; 

  final RestDatasource api = new RestDatasource();
  String token;
  StreamController _dealsController;

  @override
  void initState() {
    super.initState();
    _dealsController = new StreamController();
    _loadingDeals();
  }

  _loadingDeals() async {
    SharedPreferences prefs = await SharedPreferences.getInstance();

    this.token = prefs.getString('token');

    final res =
        this.api.checkInterests(this.token).then((interestResponse) async {
      _dealsController.add(interestResponse);
      return interestResponse;
    });
    return res;
  }

  _handleRefresh(data) async {
    SharedPreferences prefs = await SharedPreferences.getInstance();

    final token = prefs.getString('token');
    await this.api.checkInterests(token).then((interestResponse) {
      _dealsController.add(interestResponse);
    });
    return null;
  }

  @override
  Widget build(BuildContext context) {
    super.build(context); // <-- this is with the wantKeepAlive thing
    return StreamBuilder(
      stream: _dealsController.stream,
      builder: (BuildContext context, AsyncSnapshot snapshot) {

        if (snapshot.hasError) {
          ...
        }

        if (snapshot.connectionState != ConnectionState.done) {
          return Center(
            child: CircularProgressIndicator(),
          );
        }

        if (!snapshot.hasData &&
            snapshot.connectionState == ConnectionState.done) {
          return Text('No deals');
        }

        if (snapshot.hasData) {
          return ListView.builder(
                physics: const AlwaysScrollableScrollPhysics(),
                itemCount: snapshot.data['deals'].length,
                itemBuilder: (context, index) {
                  final Map deal = snapshot.data['deals'][index];
                  return ListTile(
                      onTap: () {
                        Navigator.push(
                          context,
                          MaterialPageRoute(
                            builder: (context) => DealsDetailPage(
                                  dealDetail: deal,
                                ),
                          ),
                        );
                      },
                      title: Text(deal['name']),
                      subtitle: Text(deal['expires']),
                    );
                },
              ),
        }
      },
    );
  }
}
like image 566
KhoPhi Avatar asked Aug 02 '18 23:08

KhoPhi


People also ask

How do you use FutureBuilder in flutter?

Show a constructor and parameters of Streambuilder. That is the way to utilize FutureBuilder in Flutter. You need to make a Future and pass it as the future argument. The snapshots of the Future will be passed to the builder function, in which you can decide the format to be shown depending on the current snapshot.

Why is FutureBuilder 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.

Why is FutureBuilder called multiple times?

Why FutureBuilder Called again? This is due to state changes that come if setState() called, which triggers build() method, and due to this inside widgets will be re-initialize again.


1 Answers

Using StreamBuilder is a solution, however, to trigger the FutureBuilder programmatically, just call setState, it'll rebuild the Widget.

return RefreshIndicator(
  onRefresh: () {
          setState(() {});
        },
    ...
)
like image 123
Steev James Avatar answered Oct 12 '22 01:10

Steev James