Flutter Riverpod Future Provider – Example

Aysynchronous operations are in almost every application that works with a backend. Whether it is GraphQL, Rest or anything else, you have the same pattern. You start the request, you wait till it is done and then show the data. In Flutter, Riverpod provides the FutureProvider. By using FutureProvider, the UI will be able to read the state of the future synchronously, handle the loading/error states, and rebuild when the future completes.

Setup the Project

Before we can start with coding, we are going to add some dependencies to the project. We will need Flutter Hooks, and Hooks Riverpod for the state management.

dependencies:
  flutter:
    sdk: flutter
  flutter_hooks: ^0.15.0
  hooks_riverpod: ^0.12.4

Do not forget to install the dependency, running the following command:

flutter pub get

Creating the Repository

First we are going to create a fake wrapper that retrieves a list of articles. Since we want some delay we are going to return the articles with a delay. For the article we will simply use an id and a title.

abstract class ArticleRepository {
  Future> fetchArticles();
}

class FakeArticleRepository implements ArticleRepository {
  @override
  Future> fetchArticles() {
    return Future.delayed(
      Duration(milliseconds: 500),
      () {
        return [
          Article("Article 1", 1),
          Article("Article 2", 2),
          Article("Article 3", 3),
          Article("Article 4", 4),
          Article("Article 5", 5),
          Article("Article 6", 6),
          Article("Article 7", 7)
        ];
      },
    );
  }
}

class Article {
  final String name;
  final int id;

  Article(this.name, this.id);
}

Creating the Future Provider

To access the fake articles, we create a provider of the ArticleRepository. We can access this repository in the FutureProvider. The FutureProvider will simply return the list of articles that are returned by the FakeArticleRepository.

final articleRepository = Provider(
  (ref) => FakeArticleRepository(),
);

final articles = FutureProvider>((ref) async {
  return ref.watch(articleRepository).fetchArticles();
});

Using the article’s future provider is pretty straightforward. We can create a new HookWidget, where we can use the useProvider hook to retrieve the articles. We can use the when function on the Future that is retrieved by the hook. Based on the current state, we can return the right widget. When the articles are loading we will return the CircularProgressIndicator. If the articles are ready, we can display them with a simple ListView and ListTile.

class ArticleList extends HookWidget {
  @override
  Widget build(BuildContext context) {
    final article = useProvider(articles);
    return article.when(
        loading: () => Center(child: const CircularProgressIndicator()),
        error: (err, stack) => Text('Error: $err'),
        data: (articles) {
          return Flexible(
            child: ListView.builder(
                itemCount: articles.length,
                itemBuilder: (BuildContext context, int index) {
                  return ListTile(
                      title: Text(articles[index].name),
                      subtitle: Row(
                        children: [
                          Icon(Icons.thumb_up),
                          Text(" ${articles[index].likes}")
                        ],
                      ));
                }),
          );
        });
  }
}

The full code can be found here on Github. If you still have any questions, remarks, or suggestions, do not hesitate to leave a comment or send a message!

Leave a Reply