CodeBlanks Logo Icon CodeBlanks

Summary - Riverpod advanced

Combine StateNotifier and AsyncValue to make an API screen.

Combining StateNotifier and AsyncValue

On an API screen you combine state management and async state modelling by using StateNotifier<AsyncValue<T>>. The constructor sets the initial loading state and starts loading data. AsyncValue.guard runs the Future safely: on success it switches to data, on error to error.

class UserNotifier extends StateNotifier<AsyncValue<String>> {
  UserNotifier() : super(const AsyncValue.loading()) {
    _load();
  }
  Future<void> _load() async {
    state = const AsyncValue.loading();
    state = await AsyncValue.guard(() async => 'Ayşe');
  }
}

Practice Write a UserNotifier class

Write a class named UserNotifier that extends StateNotifier<AsyncValue<String>>. The constructor should start with super(const AsyncValue.loading()) and call _load. _load should first set loading, then update the state with AsyncValue.guard(() async => 'Ayşe'). In main, create an instance, await _load, and print the value in the data case of state.when.

Starter code

main.dart
import 'package:flutter_riverpod/flutter_riverpod.dart';

// UserNotifier sınıfını yaz
// StateNotifier<AsyncValue<String>> türet
// loading ile başlat, _load çağır
// _load 'Ayşe' değerini güvenli biçimde yükle

void main() async {
  // UserNotifier oluştur, bekle, when ile yazdır
}

Sample solution

main.dart
import 'package:flutter_riverpod/flutter_riverpod.dart';

class UserNotifier extends StateNotifier<AsyncValue<String>> {
  UserNotifier() : super(const AsyncValue.loading()) {
    _load();
  }
  Future<void> _load() async {
    state = const AsyncValue.loading();
    state = await AsyncValue.guard(() async => 'Ayşe');
  }
}

void main() async {
  final notifier = UserNotifier();
  await notifier._load();
  notifier.state.when(
    data: (s) => print(s),
    loading: () => print('Yükleniyor'),
    error: (e, s) => print('Hata'),
  );
}

Expected output

Ayşe

Questions and answers

Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.

1 What does AsyncValue.guard do?

  • Runs the Future, switches to data on success or error on failure Correct answer
  • Cancels the Future
  • Only sets the loading state
  • Converts a Stream into a Future

Explanation: guard runs the Future passed to it and converts the result into the appropriate AsyncValue; you do not have to write try/catch.

2 Load with AsyncValue.guard

Question
state = await AsyncValue.____(() async => 'Ayşe');
Answer
state = await AsyncValue.guard(() async => 'Ayşe');

Explanation: The guard method runs the Future and converts the result into an AsyncValue.

3 API screen parts

Term Meaning
StateNotifier<AsyncValue<T>> Holds async state
AsyncValue.guard Wraps a Future safely
super(AsyncValue.loading()) Initial loading
when Handles all three states

All lessons in Advanced