Skip to content

Instantly share code, notes, and snippets.

@biniama
Last active December 8, 2022 13:12
Show Gist options
  • Save biniama/4ba5140f525f8717bef367872484611b to your computer and use it in GitHub Desktop.
Save biniama/4ba5140f525f8717bef367872484611b to your computer and use it in GitHub Desktop.
AsyncNotifier and AsyncNotifierProvider Example for Flutter
//Add the following in `pubspec.yaml`
dependencies:
flutter_riverpod: ^2.1.1
//If you want to run the example, you also need to install `shared_preferences: ^2.0.13`
//More documentation can be found at //https://codewithandrea.com/articles/flutter-riverpod-async-notifier/
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../shared_preferences_utils.dart';
void main() async {
// Adding ProviderScope enables Riverpod for the entire project
runApp(ProviderScope(child: MyApp()));
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'AsyncNotifer Example',
debugShowCheckedModeBanner: false,
home: FavScreen()
);
}
}
final favProvider = AsyncNotifierProvider<FavNotifier, List<String>>(FavNotifier.new);
class FavNotifier extends AsyncNotifier<List<String>> {
@override
FutureOr<List<String>> build() {
return loadFavs();
}
toggle(taskId) async {
update((_) async {
state = const AsyncLoading();
return await updateFavs(taskId);
});
}
}
class FavScreen extends ConsumerWidget {
final List<Map<String, String>> data = [
{"id": '1', 'title': '1'},
{"id": '2', 'title': '2'},
{'id': '3', 'title': '3'},
{'id': '4', 'title': '4'}
];
@override
Widget build(BuildContext context, WidgetRef ref) {
return Scaffold(
appBar: AppBar(
title: Text('State Management with RiverPod!'),
),
body: Column(
children: data.map((element) => FavItem(fav: element)).toList(),
),
);
}
}
class FavItem extends ConsumerWidget {
final Map<String, String> fav;
const FavItem({Key? key, required this.fav}) : super(key: key);
@override
Widget build(BuildContext context, WidgetRef ref) {
// watch the AsyncProvider
final favAsync = ref.watch(favProvider);
// use pattern matching to map the state to the UI
return favAsync.when(
loading: () => const CircularProgressIndicator(),
error: (err, stack) => Text('Error: $err'),
data: (result) {
return Padding(
padding: const EdgeInsets.all(18.0),
child: Row(
children: [
Checkbox(
onChanged: (newValue) =>
ref.read(favProvider.notifier).toggle(fav['id']!),
value: result.contains(fav['id']),
),
Text(fav['title']!),
],
),
);
},
);
}
}
import 'package:shared_preferences/shared_preferences.dart';
Future<List<String>> updateFavs(String favId) {
return SharedPreferences.getInstance().then((prefs) {
print('[in updateFavs] received favId $favId');
return loadFavSongs().then((result) {
result.contains(favId)
? result.remove(favId)
: result.add(favId);
prefs.setStringList('my_favorites', result);
print('[in updateFavs] updated result $result');
return result;
});
});
}
Future<List<String>> loadFavs() {
return SharedPreferences.getInstance().then((prefs) {
List<String>? favIds = prefs.getStringList('my_favorites') ?? List<String>.empty(growable: true);
print("Retrieved List of Favorites $favIds");
return favIds;
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment