'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