Module 1
Topic 7

FutureProvider

Handling asynchronous data in Riverpod — loading states, error handling, and working with Futures.

Riverpod – FutureProvider Guide Flutter Docs – Fetch Data
What Is FutureProvider?

FutureProvider is a type of provider in Riverpod that holds a Future . It's designed specifically for asynchronous operations like:

  • Making API calls (HTTP requests)
  • Reading from a database
  • Fetching data from local storage
  • Any operation that returns a Future

The key benefit of FutureProvider is that it handles the loading, data, and error states for you . Your UI can react to each state appropriately.

✅ When to Use FutureProvider

Use FutureProvider when you need to fetch data asynchronously and display it in your UI. It's perfect for API calls, database reads, and any operation that takes time to complete.

Defining a FutureProvider

Defining a FutureProvider is similar to a regular provider, but the creation function is marked as async and returns a Future .

🔑 Key Points

  • The creation function is marked with async
  • It returns a Future of the desired type
  • The provider is read-only — you can't modify the data directly
  • To refresh the data, use ref.refresh(provider)
Reading a FutureProvider

When you watch a FutureProvider , you get an AsyncValue object that represents the current state of the asynchronous operation.

Step-by-Step Explanation
1.
Define the Provider userProvider is a FutureProvider that fetches a User from an API. The async function makes the HTTP request and returns the parsed user.
2.
Watch the Provider ref.watch(userProvider) returns an AsyncValue that represents the current state of the future: loading, error, or data.
3.
Handle States – The .when() method handles all three states: loading shows a progress indicator, error shows an error message, and data displays the user's name.
4.
Automatic Caching – The result is cached after the first successful fetch. Subsequent reads return the cached data immediately without refetching.
The Three States of AsyncValue

AsyncValue is a sealed class that represents the three possible states of a Future :

Loading
The Future is currently executing. Show a loading indicator.
Error
The Future completed with an error. Show an error message.
Data
The Future completed successfully with data. Display the data.
Refreshing FutureProvider Data

By default, FutureProvider caches the result after the first successful fetch. To refetch the data (for example, when the user pulls to refresh), use ref.refresh() .

💡 Refresh vs. Watch

  • ref.watch() – Reads the provider and listens for changes
  • ref.refresh() – Invalidates the cached data and triggers a new fetch
  • ref.invalidate() – Marks the data as invalid without refetching (it will refetch on next watch)
Complete Example: Weather App

Here's a complete example of a weather app that uses FutureProvider to fetch weather data from an API. This demonstrates loading, error, and data states in a real-world scenario.

FutureProvider vs StateProvider

FutureProvider

  • Handles asynchronous data
  • Built-in loading state
  • Built-in error state
  • Read-only (cannot modify data)
  • Data is cached after fetch
  • Perfect for API calls, database reads

StateProvider

  • Handles synchronous data
  • No loading state
  • No error state
  • Mutable (can modify data)
  • Data is not cached
  • Perfect for counters, toggles, form data
Common Mistakes
❌ Mistake 1: Not handling the loading state

If you don't handle the loading state, your UI might show an empty or incorrect state while the data is being fetched. Always handle all three states of AsyncValue .

✅ Correct: Always handle loading state

Use .when() or .maybeWhen() to handle loading, error, and data states explicitly.

❌ Mistake 2: Using ref.watch() inside event handlers

ref.watch() should only be used inside the build() method. For event handlers, use ref.refresh() or ref.invalidate() .

✅ Correct: Use ref.refresh() in event handlers

For refresh buttons or retry logic, use ref.refresh(provider) to trigger a new fetch.

❌ Mistake 3: Not handling errors gracefully

If an API call fails and you don't handle the error state, your app will show a red screen. Always handle the error state and provide a way for the user to retry.

✅ Correct: Show error messages and retry buttons

In the error state, show a friendly error message and a button to retry the operation.

🎯 Key Takeaway

FutureProvider is the go-to solution for handling asynchronous data in Riverpod. It handles loading and error states automatically, caches results, and provides a clean API for refreshing data. Use it for all your API calls and async operations.