'Flutter Bloc Not updating immediately, only after a refresh or rebuild
I am working on a flutter project, so I was trying to use Flutter bloc state management. I built everything from state to event and also the bloc thing. like the code below:
State:
abstract class UserState extends Equatable {
const UserState();
@override
List<Object> get props => [];
}
class UserInitialState extends UserState {}
class UserLoadingState extends UserState {
@override
List<Object> get props => [];
}
class UserLoadedState extends UserState {
final UserModel user;
const UserLoadedState(this.user);
@override
List<Object> get props => [user];
}
class UserValidationState extends UserState {
final Map<String, dynamic> validation;
const UserValidationState(this.validation);
@override
List<Object> get props => [validation];
}
class UserErrorState extends UserState {
final Map<String, dynamic> error;
const UserErrorState(this.error);
@override
List<Object> get props => [error];
}
Event:
class LoginUserEvent extends UserEvent {
final String email, password;
const LoginUserEvent({this.email, this.password});
@override
List<Object> get props => [];
}
Bloc:
UserBloc(this._userReprository) : super(UserInitialState()) {
on<LoginUserEvent>((event, emit) async {
emit(UserLoadingState());
try {
await _userReprository
.loginUser(
email: event.email,
password: event.password,
)
.then((result) {
if (result.contains('success')) {
emit(UserLoadedState(result[1]));
} else if (result.contains('errors')) {
emit(UserValidationState(result[1]));
}
});
} catch (e) {
emit(UserErrorState(e));
}
});
}
so it should work like when I click on the button it switch to loading event then after response it either load or throw a validation error or it catch an error if something happened. well unfortunately the UI is not updating immedtialy, only after a second refresh or a setstate of another way or something that rebuild it it only change Here is the code of the UI:
@override
Widget build(BuildContext context) {
final deviceSize = MediaQuery.of(context).size;
// Clearing all TextEdititng Controller Values
_clearValues() {
_email.clear();
_password.clear();
_valErrors.clear();
}
return Scaffold(
body: SingleChildScrollView(
scrollDirection: Axis.vertical,
child: Container(
margin: EdgeInsets.only(top: deviceSize.height * 0.05),
child: Column(
children: [
Container(
margin: const EdgeInsets.symmetric(vertical: 20),
child: Material(
shadowColor: Colors.black54,
color: Theme.of(context).colorScheme.primary,
elevation: 2,
borderRadius: BorderRadius.circular(35),
child: Padding(
padding: const EdgeInsets.symmetric(
vertical: 10,
horizontal: 15,
),
child: SvgPicture.asset(
'./assets/img/auth_logo.svg',
width: deviceSize.width * 0.5,
height: deviceSize.width * 0.5,
),
),
),
),
const SizedBox(
height: 10,
),
Column(
children: <Widget>[
Container(
margin: const EdgeInsets.symmetric(horizontal: 20),
child: Material(
borderRadius: BorderRadius.circular(25),
elevation: 2,
shadowColor: Colors.black54,
child: TextField(
keyboardType: TextInputType.emailAddress,
textInputAction: TextInputAction.next,
controller: _email,
decoration: InputDecoration(
prefixIcon: const Icon(Icons.email),
border: OutlineInputBorder(
borderSide: const BorderSide(
color: Colors.white, width: 32.0),
borderRadius: BorderRadius.circular(25.0),
),
labelText: 'Email',
),
),
),
),
_valErrors.containsKey('email')
? Column(
children: <Widget>[
Align(
alignment: Alignment.centerLeft,
child: Padding(
padding: const EdgeInsets.symmetric(
horizontal: 30,
vertical: 1,
),
child: Text(
_valErrors['email'],
textAlign: TextAlign.start,
style: const TextStyle(
color: Colors.red,
),
),
),
),
const SizedBox(
height: 15,
)
],
)
: const SizedBox(
height: 25,
),
],
),
Container(
margin: const EdgeInsets.symmetric(horizontal: 20),
child: Material(
elevation: 2,
shadowColor: Colors.black54,
borderRadius: BorderRadius.circular(25),
child: TextField(
textInputAction: TextInputAction.done,
obscureText: hiddenContent,
controller: _password,
keyboardType: TextInputType.text,
decoration: InputDecoration(
prefixIcon: const Icon(Icons.lock),
suffixIcon: IconButton(
icon: hiddenContent
? const Icon(Icons.visibility)
: const Icon(Icons.visibility_off),
onPressed: () {
setState(() {
hiddenContent = !hiddenContent;
});
}),
border: OutlineInputBorder(
borderSide:
const BorderSide(color: Colors.white, width: 32.0),
borderRadius: BorderRadius.circular(25.0),
),
labelText: 'Password',
),
),
),
),
_valErrors.containsKey('password')
? Column(
children: <Widget>[
Align(
alignment: Alignment.centerLeft,
child: Padding(
padding: const EdgeInsets.symmetric(
horizontal: 30, vertical: 1),
child: Text(
_valErrors['password'],
textAlign: TextAlign.start,
style: const TextStyle(
color: Colors.red,
),
),
),
),
const SizedBox(
height: 15,
)
],
)
: const SizedBox(
height: 25,
),
BlocBuilder<UserBloc, UserState>(
builder: (context, state) {
if (state is UserLoadingState) {
return const CircularProgressIndicator();
}
return Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Material(
elevation: 2,
shadowColor: Colors.black54,
borderRadius: BorderRadius.circular(25),
child: TextButton(
style: ButtonStyle(
padding: MaterialStateProperty.all<EdgeInsets>(
const EdgeInsets.symmetric(
vertical: 15,
horizontal: 30,
),
),
shape: MaterialStateProperty.all<
RoundedRectangleBorder>(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(25),
),
),
backgroundColor: MaterialStateProperty.all<Color>(
Theme.of(context).colorScheme.primary,
),
),
onPressed: () async {
// If Statement to make sure THe validation is correct and to show Messages
setState(() {
if (_email.text.isEmpty) {
_valErrors['email'] = 'This Field is Required';
} else {
_valErrors.remove('email');
}
if (_password.text.isEmpty) {
_valErrors['password'] =
'This Field is Required';
} else if (_password.text.length < 8) {
_valErrors['password'] =
'Password must be Greater Than 8';
} else {
_valErrors.remove('password');
}
});
// Databse Function Login
if (_valErrors.isEmpty) {
context.read<UserBloc>().add(
LoginUserEvent(
email: _email.text,
password: _password.text,
),
);
if (state is UserLoadedState) {
_clearValues();
Navigator.of(context)
.pushReplacementNamed('/botnavbar');
} else if (state is UserValidationState) {
showDialog(
context: context,
builder: (context) {
return AlertDialog(
title: const Text(
'There is some problems'),
content: Text(state
.validation['message']
.toString()),
actions: <Widget>[
TextButton(
onPressed: () =>
Navigator.of(context).pop(),
child: const Text('Okay'),
),
],
);
});
}
}
},
child: const Text(
'Login',
style: TextStyle(
fontSize: 20,
color: Colors.white,
),
),
),
),
Material(
elevation: 2,
shadowColor: Colors.black54,
borderRadius: BorderRadius.circular(25),
child: TextButton(
style: ButtonStyle(
padding: MaterialStateProperty.all<EdgeInsets>(
const EdgeInsets.symmetric(
vertical: 15,
horizontal: 35,
),
),
shape: MaterialStateProperty.all<
RoundedRectangleBorder>(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(25),
side: BorderSide(
color: Theme.of(context).colorScheme.primary,
),
),
),
),
onPressed: () {
Navigator.of(context)
.pushReplacementNamed('/register');
},
child: Text(
'Register',
style: TextStyle(
fontSize: 20,
color: Theme.of(context).colorScheme.primary,
),
),
),
),
],
);
},
),
],
),
),
),
);
}
I tried to use the blocbuilder on the whole scaffold but still the same problem Hope you can help me guys
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
