I have a class called NavigatorRepository
that I am trying to access, userProvider
. How should I be accessing the userProvider inside the NavigatorRepository
? I feel like i've tried everything, except the right thing...
Here is a snippet from NavigatorRepository
final user = Provider((ref) {
return ref.watch(userProvider.notifier).getUser();
});
...
class NavigatorRepository {
...
Future<dynamic> _get(
String path, {
Map<String, Object?>? queryParameters,
}) async {
var x = user; <== How do I get this to work?
}
}
UserProvider
class UserNotifier extends StateNotifier<User> {
UserNotifier()
: super(User(accessToken: '');
void setUser(User user) {
state = user;
}
User getUser() {
return state;
}
}
final userProvider = StateNotifierProvider<UserNotifier, User>((ref) {
return UserNotifier();
});
There are many ways to do this.
final navigatorProvider = NotifierProvider<NavigatorRepository, void>(() {
return NavigatorRepository();
});
class NavigatorRepository extends Notifier<void> {
@override
void build() {
// you can use ref.watch in this method
User user = ref.watch(userProvider);
}
func() {
// ref is available in any methods of the NavigatorRepository class
ref.read(...);
}
ref
parameter to the class constructor:final navigatorProvider = Provider<NavigatorRepository>(NavigatorRepository.new);
class NavigatorRepository {
NavigatorRepository(this._ref);
final Ref _ref;
func() {
// ref is available in any methods of the NavigatorRepository class
_ref.read(...);
}
}
final navigatorProvider = Provider<NavigatorRepository>((ref) {
return NavigatorRepository(
authService: ref.watch(AuthService),
settingService: ref.watch(SettingService),
userService: ref.watch(UserService),
);
});
class NavigatorRepository {
UserService({
required AuthService authService,
required SettingService settingService,
required UserService userService,
}) : _authService = authService,
_settingService = settingService,
_UserService = userService;
final AuthService _authService;
final SettingService _settingService;
final UserService _userService;
func() {
// simply call the method
User user = _userService.getUser();
}
}
The idea is that you pass all necessary dependencies immediately to the constructor of your class. In the end, you know for sure that your class-service only depends on the services that are in the constructor.
Note also that I have made all services private to avoid outside access. If you don't need it, make the fields open.
ref
parameter when calling any method:class NavigatorRepository {
...
Future<dynamic> _get(
Ref ref,
String path, {
Map<String, Object?>? queryParameters,
}) async {
var user = ref.read(userProvider);
}
}
Although here you could pass User user
as a parameter to the method and use it inside. But apparently there can be more such dependencies and then it is easier just to pass ref
.