我正在做一个带注释的河荚项目,在我做了同样的项目后,没有注释.我试图调整我在第一个项目中拥有的所有提供程序,但在访问_authNotifier.addListener时遇到问题,因为它告诉我它尚未定义.
我不知道发生了什么事,所以你能帮我会很有帮助的!
This is my first project's code and it works perfect
**auth_provider.dart**
个个
final authProvider = StateNotifierProvider<AuthNotifier, AuthState>((ref) {
final authRepository = AuthRepositoryImpl();
final keyValueStorageService = KeyValueStorageServiceImpl();
return AuthNotifier(
authRepository: authRepository,
keyValueStorageService: keyValueStorageService,
);
});
class AuthNotifier extends StateNotifier<AuthState> {
final AuthRepository authRepository;
final KeyValueStorageService keyValueStorageService;
AuthNotifier({
required this.authRepository,
required this.keyValueStorageService,
}) : super(AuthState()) {
checkAuthStatus();
}
Future<void> loginUser(String email, String password) async {
try {
final user = await authRepository.login(email, password);
_setLoggedUser(user);
} on CustomError catch (e) {
logout(e.message);
} catch (e) {
logout('Error no controlado');
}
}
void registerUser(String email, String password, String fullName) async {}
void checkAuthStatus() async {
final token = await keyValueStorageService.getKeyValue<String>('token');
if (token == null) return logout();
try {
final user = await authRepository.checkAuthStatus(token);
_setLoggedUser(user);
} catch (e) {
logout();
}
}
_setLoggedUser(User user) async {
await keyValueStorageService.setKeyValue('token', user.token);
state = state.copyWith(
user: user,
authStatus: AuthStatus.authenticated,
errorMessage: '',
);
}
Future<void> logout([String? errorMessage]) async {
await keyValueStorageService.removeKey('token');
state = state.copyWith(
authStatus: AuthStatus.unauthenticated,
user: null,
errorMessage: errorMessage,
);
}
}
enum AuthStatus { checking, authenticated, unauthenticated }
class AuthState {
final AuthStatus authStatus;
final User? user;
final String errorMessage;
AuthState({
this.authStatus = AuthStatus.checking,
this.user,
this.errorMessage = '',
});
AuthState copyWith({
AuthStatus? authStatus,
User? user,
String? errorMessage,
}) =>
AuthState(
authStatus: authStatus ?? this.authStatus,
user: user ?? this.user,
errorMessage: errorMessage ?? this.errorMessage,
);
}
**app_router_notifier.dart**
个个
final goRouterNotifierProvider = Provider((ref) {
final authNotifier = ref.read(authProvider.notifier);
return GoRouterNotifier(authNotifier);
});
class GoRouterNotifier extends ChangeNotifier {
final AuthNotifier _authNotifier;
AuthStatus _authStatus = AuthStatus.checking;
GoRouterNotifier(this._authNotifier) {
_authNotifier.addListener((state) {
authStatus = state.authStatus;
});
}
AuthStatus get authStatus => _authStatus;
set authStatus(AuthStatus value) {
_authStatus = value;
notifyListeners();
}
}
Now this is my second project using annotations (Here is the problem)
**auth_provider.dart**
个个
part 'auth_provider.g.dart';
@Riverpod(keepAlive: true)
class Auth extends _$Auth {
final authRepository = AuthRepositoryImpl();
final keyValueStorageService = KeyValueStorageServiceImpl();
@override
AuthState build() {
checkAuthStatus();
return AuthState();
}
Future<void> loginUser(String email, String password) async {
try {
final user = await authRepository.login(email, password);
_setLoggedUser(user);
} on CustomError catch (e) {
logout(e.message);
} catch (e) {
logout('Error no controlado');
}
}
void registerUser(String email, String password, String username) async {}
void checkAuthStatus() async {
final token = await keyValueStorageService.getKeyValue<String>('token');
if (token == null) return logout();
try {
final user = await authRepository.checkAuthStatus(token);
_setLoggedUser(user);
} catch (e) {
logout();
}
}
_setLoggedUser(User user) async {
await keyValueStorageService.setKeyValue('token', user.token);
state = state.copyWith(
user: user,
authStatus: AuthStatus.authenticated,
errorMessage: '',
);
}
Future<void> logout([String? errorMessage]) async {
await keyValueStorageService.removeKey('token');
state = state.copyWith(
authStatus: AuthStatus.unauthenticated,
user: null,
errorMessage: errorMessage,
);
}
}
enum AuthStatus { checking, authenticated, unauthenticated }
class AuthState {
final AuthStatus authStatus;
final User? user;
final String errorMessage;
AuthState({
this.authStatus = AuthStatus.checking,
this.user,
this.errorMessage = '',
});
AuthState copyWith({
AuthStatus? authStatus,
User? user,
String? errorMessage,
}) =>
AuthState(
authStatus: authStatus ?? this.authStatus,
user: user ?? this.user,
errorMessage: errorMessage ?? this.errorMessage,
);
}
**app_router_notifier.dart**
个个
part 'app_router_notifier.g.dart';
@Riverpod(keepAlive: true)
GoRouterNotifier goRouterNotifier(Ref ref) {
final authNotifier = ref.read(authProvider.notifier);
return GoRouterNotifier(authNotifier);
}
class GoRouterNotifier extends ChangeNotifier {
final Auth _authNotifier;
AuthStatus _authStatus = AuthStatus.checking;
GoRouterNotifier(this._authNotifier) {
_authNotifier.addListener((state) {
authStatus = state.authStatus;
});
}
AuthStatus get authStatus => _authStatus;
set authStatus(AuthStatus value) {
_authStatus = value;
notifyListeners();
}
}
So what is the problem?
正如你所看到的,我正试着做同样的事情,但在这条线上是app_router_notifier.dart
:
_authNotifier.addListener((state) {
authStatus = state.authStatus;
});
I'm getting this error:没有为类型"Auth"定义方法"addListener". 请try 将名称更正为现有方法的名称,或定义名为"addListener"的方法.
我try 了不同的解决方案,即使是在人工智能方面也是如此.我认为我的auth_Provider.dart中有问题,但我不确定是什么问题.我相信.addListener
在StateNotifier
中,但它不在生成Riverpod的NotifierProvider中.
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'auth_provider.dart';
// **************************************************************************
// RiverpodGenerator
// **************************************************************************
String _$authHash() => r'baf96bdb5085978702d0e2b04c3a2e56893b8a41';
/// See also [Auth].
@ProviderFor(Auth)
final authProvider = NotifierProvider<Auth, AuthState>.internal(
Auth.new,
name: r'authProvider',
debugGetCreateSourceHash:
const bool.fromEnvironment('dart.vm.product') ? null : _$authHash,
dependencies: null,
allTransitiveDependencies: null,
);
typedef _$Auth = Notifier<AuthState>;
// ignore_for_file: type=lint
// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member, inference_failure_on_uninitialized_variable, inference_failure_on_function_return_type, inference_failure_on_untyped_parameter
还有其他一些对我不起作用的"解决方案":
_authNotifier.listen<AuthStatus>((state) {
authStatus = state.authStatus;
});
_authNotifier.ref.listen(authProvider.notifier, (_, currentState) {
authStatus = currentState.state.authStatus;
});
_authNotifier.addListener((state) {
final authState = _authNotifier.build();
authStatus = authState.authStatus;
});
A little bit of context of the application
我正在后端(NestJS+GraphQL)使用Ffltter、Dart、Riverpod和Go Router进行登录和注册,在下面的文件中,如果没有有效的令牌,我将try 重定向用户.这就是我使用goRouterNotify的地方,这样它就可以在状态更改时侦听并重定向用户.
part 'app_router.g.dart';
@Riverpod(keepAlive: false)
GoRouter goRouter(GoRouterRef ref) {
final goRouterNotifier = ref.read(goRouterNotifierProvider);
return GoRouter(
initialLocation: '/login',
refreshListenable: goRouterNotifier,
routes: [
//* First Route
GoRoute(
path: '/checking',
builder: (context, state) => const CheckAuthStatusScreen(),
),
//* Shared Routes
GoRoute(
path: '/main/:page',
builder: (context, state) {
final pageIndex = state.pathParameters['page'] ?? '0';
return MainScreen(pageIndex: int.parse(pageIndex));
}),
GoRoute(
path: '/settings',
builder: (context, state) => const SettingdScreen(),
),
//* Auth Routes
GoRoute(
path: '/login',
builder: (context, state) => const LoginScreen(),
),
GoRoute(
path: '/signup',
builder: (context, state) => const SignUpScreen(),
),
//* Home Routes
],
redirect: (context, state) {
// print(state.matchedLocation);
final isGoingTo = state.matchedLocation;
final authStatus = goRouterNotifier.authStatus;
if (isGoingTo == '/checking' && authStatus == AuthStatus.checking) {
return null;
}
if (authStatus == AuthStatus.unauthenticated) {
if (isGoingTo == '/login' || isGoingTo == '/signup') return null;
return '/login';
}
if (authStatus == AuthStatus.authenticated) {
if (isGoingTo == '/login' ||
isGoingTo == '/signup' ||
isGoingTo == '/checking') return '/main/0';
}
return null;
},
);
}