I'm currently using the new Riverpod syntax but I'm having an error and haven't been able to find a solution. I need to pass a dependency but it gives me this error The class TaskHomeInit must have a default constructor. Does anyone know another way to pass the HomeRepository dependency to it. When I don't place the constructor the error is that it needs to be initialized.
@Riverpod(keepAlive: true)
class TaskHomeInit extends _$TaskHomeInit {
final HomeRepository homeRepository;
// Constructor
TaskHomeInit({required this.homeRepository}); // here is error
@override
Future<TasksHomeState> build() async {
final List<TaskHome> taskHome = await homeRepository.getTaskHome();
return TasksHomeState(isLoading: false, tasksHome: taskHome);
}
}
When I don't create the constructor, I get this error: The final variable 'homeRepository' must be initialized. Try initializing the variable.
HomeRepository abstract class
abstract class HomeRepository {
Future<List<TaskHome>> getTaskHome();
}
Implementation HomeRepository
class HomeRepositoryImpl extends HomeRepository {
final HomeDatasource datasource;
HomeRepositoryImpl(this.datasource);
@override
Future<List<TaskHome>> getTaskHome() async {
final test = await datasource.getTaskHome();
return test;
}
}
In riverpod world, dependency injection is usually done with the Ref
object.
Instead of injecting the dependency via constructor, create a provider.
@Riverpod(keepAlive: true)
HomeRepository homeRepo(HomeRepoRef ref) => HomeRepositoryImpl(ref.watch(homeDatasourceProvider);
@Riverpod(keepAlive: true)
HomeDatasource homeDatasource(HomeDatasourceRef ref) => HomeDatasourceImpl();
Inside the Notifier/AsyncNotifier
's build method, use ref.watch
to access the dependency. It is safe and recommended to use ref.watch
inside the build method.
@override
Future<TasksHomeState> build() async {
final repo = ref.watch(homeRepoProvider);
final taskHome = await repo.getTaskHome();
return ...
}