MVVMアーキテクチャ、viewModel-repositoryパターンで作ったFlutter TODO App
// define riverpod provider. using TaskRepository for parameter type to keep testability.
final taskRepositoryProvider = Provider<TaskRepository>((ref) => TaskRepositoryImpl());
class TaskRepositoryImpl implements TaskRepository {
@override
Future<List<Task>> getAllTasks() async {
final db = await databaseProvider.database;
final result = await db.rawQuery('SELECT * FROM $taskTable');
return result.map((json) => Task.fromJson(json)).toList(); // freezed json mapping
}
}
// define riverpod provider
final homeViewModelNotifierProvider = ChangeNotifierProvider((ref) => HomeViewModel(ref.read(taskRepositoryProvider)));
class HomeViewModel extends ChangeNotifier {
HomeViewModel(this._taskRepository);
final TaskRepository _taskRepository;
List<Task>? _taskList;
List<Task>? get taskList => _taskList;
// fetch tasks from repository
Future<void> fetchTaskList() {
return _taskRepository.getAllTasks().then((value) {
_taskList = value;
}).catchError((error) {
// handle errors
}).whenComplete(notifyListeners); // notifiy the data changed
}
}
class HomePage extends HookWidget {
@override
Widget build(BuildContext context) {
// injection with riverpod provider
final viewModel = useProvider(homeViewModelNotifierProvider);
useEffect(() {
viewModel.fetchTaskList();
return viewModel.dispose;
}, const []);
// use viewModel.taskList and we can get task list data from local database
return // some widget
}
}
- Flutter Hooks
- Riverpod
- ChangeNotifier
- sqflite
- MVVM
- repository pattern
- freezed