Flutter Bloc模式:嵌套API调用在事件处理程序中
我对颤动是相对较新的,并且仍然试图熟悉颤抖的集体图案。我创建了一个authbloc来处理用户身份验证。
验证流量如下:
#1-使用凭据(称为第一个端点)中的用户符号。
#2-签名成功时,我们可以访问用户访问和刷新令牌。
#3-使用检索到的访问令牌获取用户配置文件(第二个端点)。
#4-将用户令牌和用户配置文件保存到身份验证的状态。
在我的authbloc中,我想在收到loginRequested事件时一个接一个地提到的端点。我得到了这个未经治疗的例外:
发射在正常的事件处理程序完成后被调用。 这通常是由于事件处理程序中未知的未来。 请确保与活动处理程序一起等待所有异步操作
任何帮助都非常感谢!
我的代码:
/*auth_event.dart*/
// When the user signing in with login and password this event is called
// and the [AuthRepository] is called to sign in the user
class LoginRequested extends AuthEvent {
final CredentialsDTO credentials;
LoginRequested(this.credentials);
}
/*auth_state.dart*/
// When the user is authenticated the state is changed to Authenticated.
class Authenticated extends AuthState {
final String accessToken;
final String refreshToken;
final User? user;
Authenticated(this.accessToken, this.refreshToken, this.user);
@override
List<Object?> get props => [accessToken, refreshToken, user];
}
/*auth_bloc.dart*/
// On login button press, send the LoginRequested Event to the AuthBloc
// to handle it and emit the Authenticated State if the user is authenticated
on<LoginRequested>((event, emit) async {
emit(Loading());
final response = await loginUseCase!.call(
LoginParams(
login: CredentialsModel(
login: event.credentials.login,
password: event.credentials.password,
),
),
);
response.fold(
(failure) {
emit(
AuthError(ErrorObject.mapFailureToErrorObject(failure: failure)));
emit(UnAuthenticated());
},
// I am having trouble in this section of the code !
(success) async {
final accessToken = success.accessToken;
final refreshToken = success.refreshToken;
final response = await fetchProfileUseCase!.call(
FetchProfileParams(
token: SociaLoginModel(accessToken: accessToken),
),
);
response.fold(
(failure) {
emit(AuthError(
ErrorObject.mapFailureToErrorObject(failure: failure)));
emit(UnAuthenticated());
},
(success) async =>
emit(Authenticated(accessToken, refreshToken, success.user)),
);
},
);
});
I am relatively new to Flutter and still trying to get familiar with the Flutter Bloc pattern. I have created an AuthBloc to handle user authentication.
The auth flow is as follows :
#1 - user signs in using credentials (first endpoint is called).
#2 - when signing is successful we have access to user access and refresh tokens.
#3 - fetch user profile using the retrieved access token (second endpoint is called).
#4 - user tokens as well as user profile are saved to the authenticated state.
In my AuthBloc I want to call both mentioned endpoints one after the other when I receive a LoginRequested event. I am getting this unhandled exception :
emit was called after an event handler completed normally.
This is usually due to an unawaited future in an event handler.
Please make sure to await all asynchronous operations with event handlers
Any help is very much appreciated !.
My code :
/*auth_event.dart*/
// When the user signing in with login and password this event is called
// and the [AuthRepository] is called to sign in the user
class LoginRequested extends AuthEvent {
final CredentialsDTO credentials;
LoginRequested(this.credentials);
}
/*auth_state.dart*/
// When the user is authenticated the state is changed to Authenticated.
class Authenticated extends AuthState {
final String accessToken;
final String refreshToken;
final User? user;
Authenticated(this.accessToken, this.refreshToken, this.user);
@override
List<Object?> get props => [accessToken, refreshToken, user];
}
/*auth_bloc.dart*/
// On login button press, send the LoginRequested Event to the AuthBloc
// to handle it and emit the Authenticated State if the user is authenticated
on<LoginRequested>((event, emit) async {
emit(Loading());
final response = await loginUseCase!.call(
LoginParams(
login: CredentialsModel(
login: event.credentials.login,
password: event.credentials.password,
),
),
);
response.fold(
(failure) {
emit(
AuthError(ErrorObject.mapFailureToErrorObject(failure: failure)));
emit(UnAuthenticated());
},
// I am having trouble in this section of the code !
(success) async {
final accessToken = success.accessToken;
final refreshToken = success.refreshToken;
final response = await fetchProfileUseCase!.call(
FetchProfileParams(
token: SociaLoginModel(accessToken: accessToken),
),
);
response.fold(
(failure) {
emit(AuthError(
ErrorObject.mapFailureToErrorObject(failure: failure)));
emit(UnAuthenticated());
},
(success) async =>
emit(Authenticated(accessToken, refreshToken, success.user)),
);
},
);
});
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
所以我设法解决了我的问题。这是我的做法:
我没有直接调用登录事件中的提取物端点,而是重新分配了如下所示的代码。
解决方案是在处理第一个事件之后,将第二个事件添加到集团中,第二个事件Onprofilerequested将单独处理第二个API调用并更新Authstate。
So I managed to solve my issue. Here is how I did it:
Instead of directly calling the fetchProfile endpoint inside the LoginRequested Event, I refactored the code like shown below.
The solution is to add a second event to the bloc after the first one is handled, the second event OnProfileRequested will separately handle the second api call and update the AuthState.