Challenge 1
- Flutter course
- Advanced
- Lesson 66/69
- 3 min
Build API state management with StateNotifier and AsyncValue.
Challenge 1 - StateNotifier and AsyncValue
In this challenge you will create a StateNotifier<AsyncValue<List<String>>>. You wrap the API call with AsyncValue.guard, which handles loading and error states automatically.
class PostNotifier extends StateNotifier<AsyncValue<List<String>>> {
PostNotifier() : super(const AsyncValue.loading()) {
_load();
}
Future<void> _load() async {
state = await AsyncValue.guard(() async => ['a', 'b']);
}
}Practice Define PostNotifier
Define PostNotifier extending StateNotifier<AsyncValue<List<String>>>. The constructor starts with AsyncValue.loading() and calls _load(). The async _load method assigns the result of AsyncValue.guard(() async => ['post1', 'post2']) to state. In main, create a PostNotifier instance, wait 100ms, and print state.value.
Starter code
import 'package:flutter_riverpod/flutter_riverpod.dart';
// PostNotifier sınıfını tanımla (StateNotifier ve AsyncValue ile)
// constructor loading durumuyla başlasın ve _load çağırsın
// _load, state'e guard sonucunu atasın
void main() async {
// PostNotifier örneği al, kısa bekle, state value'yu yazdır
}Sample solution
import 'package:flutter_riverpod/flutter_riverpod.dart';
class PostNotifier extends StateNotifier<AsyncValue<List<String>>> {
PostNotifier() : super(const AsyncValue.loading()) {
_load();
}
Future<void> _load() async {
state = await AsyncValue.guard(() async => ['post1', 'post2']);
}
}
void main() async {
final notifier = PostNotifier();
await Future.delayed(const Duration(milliseconds: 100));
print(notifier.state.value);
notifier.dispose();
}Expected output
[post1, post2]
Practice Handle states with AsyncValue.when
In main, assign AsyncValue.data(['a', 'b']) to a variable state. Handle loading, data and error states with state.when: loading () => 'yukleniyor', data (v) => v.join(','), error (e, _) => 'hata: $e'. Print the result.
Starter code
import 'package:flutter_riverpod/flutter_riverpod.dart';
void main() {
// state değişkenine AsyncValue ile data durumu ata (liste: 'a' ve 'b')
// .when ile loading, data ve error durumlarını işle
// loading 'yukleniyor', data ile virgülle birleştir, error 'hata: $e'
// sonucu yazdır
}Sample solution
import 'package:flutter_riverpod/flutter_riverpod.dart';
void main() {
final state = AsyncValue.data(['a', 'b']);
final result = state.when(
loading: () => 'yukleniyor',
data: (v) => v.join(','),
error: (e, _) => 'hata: $e',
);
print(result);
}Expected output
a,b
Questions and answers
Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.
1 When should the state property of StateNotifier be updated?
- When async operations complete and value is ready Correct answer
- Never
- Every frame
- Only inside the constructor
Explanation: State gets its initial value in the constructor; it is updated with the guard result once async operations complete and the value is ready.
2 AsyncValue.guard call
state = await AsyncValue.____(() async => ['a', 'b']);
state = await AsyncValue.guard(() async => ['a', 'b']);
Explanation: AsyncValue.guard wraps the given async function; it returns AsyncError on failure or AsyncData on success.
3 StateNotifier and AsyncValue matches
| Term | Meaning |
|---|---|
StateNotifier |
State manager |
AsyncValue |
Async state wrapper |
guard |
Catches errors |
StateNotifierProvider |
Provider |