Я пытаюсь войти в дротик, используя cubit/bloc.
И когда я пытаюсь изменить состояние своего кубита (авторизация) на Ожидание => CircularProgressIndicator
Затем мое приложение застревает, когда api возвращает statusCode == 400, и я вызываю другую команду, чтобы показать диалоговое окно.
Но если вход выполнен успешно (statusCode == 200), то все в порядке, и я перехожу к main_page.dart.
Как решить эту проблему и передать ответ данных из API в виджет (я хочу отправить код состояния и сообщение в виджет)
Мой кубит файл:
class AuthCubit extends Cubit<AuthState> {
AuthCubit() : super(AuthState(
email: "",
password: "",
));
final ApiService _apiService = ApiService();
void setEmail(String email) => emit(state.copyWith(email: email));
void setPassword(String password) => emit(state.copyWith(password: password));
Future signIn() async {
emit(WaitingSignInAuth(state.email, state.password));
try {
final data = await _apiService.signIn(
email: state.email ?? "",
password: state.password ?? ""
);
if (data['success']) {
print(data);
emit(const SuccessAutentification());
}
} on DioError catch (ex) {
print(ex.toString());
//I want to transfer to ErrorSignInAuth ex.response!.data['message'] but I don't know how
emit(ErrorSignInAuth(state.email, state.password));
} catch (e) {
print(e);
}
}
}
Это мой файл состояния:
class AuthState extends Equatable {
final String? email;
final String? password;
const AuthState({
this.email,
this.password,
});
AuthState copyWith({
String? email,
String? password,
}) {
return AuthState(
email: email ?? this.email,
password: password ?? this.password,
);
}
@override
List<Object?> get props =>
[email, password];
}
class SuccessAutentification extends AuthState {
const SuccessAutentification() : super();
}
class WaitingSignInAuth extends AuthState {
const WaitingSignInAuth(email, password) : super(email: email, password: password);
}
class ErrorSignInAuth extends AuthState {
const ErrorSignInAuth(email, password) : super(email: email, password: password);
}
А это виджет, в котором я использую этот локоть:
@override
Widget build(BuildContext context) {
return BlocConsumer<AuthCubit, AuthState>(
listener: (context, state) {
if (state is WaitingSignInAuth) {
showDialog(
context: context,
builder: (context) => Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
color: Colors.black.withOpacity(0.6),
child: const Center(
child: CircularProgressIndicator(
strokeWidth: 1,
color: Colors.black,
backgroundColor: Colors.white,
),
),
));
}
if (state is SuccessAutentification) {
Navigator.of(context).pushReplacement(
MaterialPageRoute(
builder: (_) => const MainWidget(),
),
);
}
if (state is ErrorAuthentification) {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Text("Bad request"),
content: SingleChildScrollView(
child: ListBody(
children: <Widget>[
Text("Error") // I want to show here error message
],
),
),
actions: <Widget>[
TextButton(
child: const Text("Close"),
onPressed: () {
Navigator.of(context).pop();
},
)
],
);
}
);
}
},
builder: (context, state) {
return Scaffold(
LoginButton(
color: _isValid ? AppColors.white : AppColors.whiteA3A3A3,
text: "Login in",
textColor: Colors.black,
isButtonDisabled: _isValid ? false : true,
onPressed: () {
if (_key.currentState!.validate()) {
BlocProvider.of<AuthCubit>(context).setEmail(_email.text.trim());
BlocProvider.of<AuthCubit>(context).setPassword(_password.text.trim());
BlocProvider.of<AuthCubit>(context).signIn();
_key.currentState!.save();
}
},
)
);
},
);
}
В функции signIn()
после того, как вы выдаете состояние WaitingSignInAuth
, в некоторых случаях вы не выдаете никакого другого состояния, поэтому ваша страница всегда загружается.
Future signIn() async {
emit(WaitingSignInAuth(state.email, state.password));
try {
final data = await _apiService.signIn(
email: state.email ?? "",
password: state.password ?? ""
);
if (data['success']) {
print(data);
emit(const SuccessAutentification());
} else {
// emit state
emit(ErrorSignInAuth(state.email, state.password));
}
} on DioError catch (ex) {
print(ex.toString());
emit(ErrorSignInAuth(state.email, state.password));
} catch (e) {
print(e);
// emit state
emit(ErrorSignInAuth(state.email, state.password));
}
}