Riverpod AsyncState

Flutter tips Published on

Managing the state of your Flutter application can sometimes feel tricky, especially when dealing with data that takes time to load, might fail, or is successfully retrieved. This is where Riverpod AsyncState comes in handy, making it much easier to handle these common scenarios.

Why Use Riverpod AsyncState?

Riverpod AsyncState helps you manage your page's state in a super clear way. It lets you define how your app should look and behave when data is loading, when an error occurs, or when your data is ready to be displayed. No more manual toggling of loading indicators or complex error handling logic!

Step 1: Create Your State Notifier

First, you need to create a special notifier that tells Riverpod how to get your data. This notifier should return a Future of your state. This Future is what Riverpod watches to know if your data is loading, done, or has an error.

part 'tasks_list_notifier.g.dart';

(keepAlive: false)
class TasksListNotifier extends _$TasksListNotifier {
  
  Future<TasksListState> build() {
    return _loadTasks(TasksListTab.active)
           .then((tasks) => TasksListState(tasks: tasks));
  }
}

Important: After creating your notifier, don't forget to run the build_runner command. This tool generates the necessary Riverpod code from the annotations (like @Riverpod) you've added.

Step 2: Listen to Your State

In your widget, you can easily listen to the state provided by your notifier. This is where the magic happens, as Riverpod automatically handles the different stages for you.

final state = ref.watch(tasksListNotifierProvider);

Step 3: Handle All States Automatically

Riverpod's AsyncValue (which is what AsyncState essentially provides) comes with a handy .map() method. This allows you to define different UI based on whether your data is loading, an error occurred, or the data is successfully available. It's a clean way to show different parts of your UI based on the current state.

state.map(
  data: (data) {
    if (data.value.tasks.isEmpty) {
      return Center(
        child: Padding(
          padding: const EdgeInsets.only(top: 120.0),
          child: Text(
            "No item found",
            textAlign: TextAlign.center,
          ),
        ),
      );
    }
    return ListView.separated(
      itemCount: data.value.tasks.length,
      separatorBuilder: (context, index) => const SizedBox(height: 12),
      itemBuilder: (context, index) => TaskCard(task: data.value.tasks[index]),
    );
  },
  error: (error) => Center(
    child: Text(
      'Error',
      style: context.textTheme.headlineMedium?.copyWith(
        color: context.colors.error,
      ),
    ),
  ),
  loading: (loading) => Center(
    child: CircularProgressIndicator.adaptive(
      backgroundColor: context.colors.primary,
    ),
  ),
);

As you can see, with Riverpod AsyncState, you get a clear and structured way to manage asynchronous data flows in your Flutter app, making your code cleaner and easier to maintain. You define what happens for each state, and Riverpod takes care of the rest!

Save 3 months of work

Create your app using our 6 years of making Flutter apps and more than 50+ apps

kickstarter for flutter apps

Frequently Asked Questions

What is Riverpod AsyncState?

Riverpod AsyncState is a powerful feature in Riverpod that helps you manage data that takes time to load, might fail, or is successfully retrieved. It simplifies showing different parts of your app's user interface (UI) based on these states: loading, error, and data.

How do I create a notifier for Riverpod AsyncState?

You create a notifier by extending `_$` followed by your notifier name (e.g., `_$TasksListNotifier`) and overriding the `build()` method to return a `Future` of your desired state. Remember to add the `@Riverpod` annotation.

How does Riverpod handle different states (loading, error, data) automatically?

Once you listen to your notifier's state using `ref.watch()`, the returned `AsyncValue` provides a `.map()` method. This method lets you define separate UI widgets for `data`, `error`, and `loading` states, so Riverpod can show the correct UI automatically.

What is `build_runner` used for with Riverpod?

`build_runner` is a tool that generates extra code for Riverpod based on your annotations (like `@Riverpod`). This generated code is essential for Riverpod to work correctly, especially for setting up `AsyncNotifier` and other providers.

Read more
You may also be interested in
Getting device timezone  blog card image
Getting device timezone
Published on 2025-11-28T16:54:52.958Z
Render widget outside of parent bounds  blog card image
Render widget outside of parent bounds
Published on 2025-11-28T16:57:11.793Z
ApparenceKit is a flutter template generator tool by Apparence.io © 2025.
All rights reserved