Search code examples
flutterblocflutter-bloc

Why "StateError (Bad State: add(LoginPasswordChange) was called without a registered event handler" error?


This is the code i copied from YouTube, and I had to change several lines, because flutter bloc had a new update, but the error still happened.

  Widget _passwordField() {
    return BlocBuilder<LoginBloc, LoginState>(builder: (context, state) {
      return TextFormField(
        obscureText: true,
        decoration: const InputDecoration(
          icon: Icon(Icons.security),
          hintText: 'Password',
        ),
        validator: (value) =>
            state.isValidPassword ? null : 'Password is too short',
        onChanged: (value) => context.read<LoginBloc>().add(
              LoginPasswordChanged(password: value),
            ),
      );
    });
  }

The above code where the compiler throws an error, specifically on "Onchange: (value)"

class LoginBloc extends Bloc<LoginEvent, LoginState> {
   final AuthRepository authRepo;
  Exception? get exception => null;
 LoginBloc(this.authRepo) : super(LoginInitial()) {
   // ignore: unused_element
   on<LoginEvent>(event, emit)
   async*{

    if(emit is LoginUsernameChanged){
      yield state.copyWith(username: emit.username);
    } else if (emit is LoginPasswordChanged){
      yield state.copyWith(password: emit.password);
    } else if (emit is LoginSubmitted){
      yield state.copyWith(formStatus: FormSubmitting());

      try{
        await authRepo.login();
        yield state.copyWith(formStatus: SubmissonSuccess());
      } catch (e){
        yield state.copyWith(formStatus: SubmissionFailed(exception!, e));
      }
    }
  }
}
}

The above code is definitely i change from MaptoEvent to on(event,emit) due to the new flutter bloc update.

I tried changing the code in event. Bloc. Is there anymore lines i need to change that seem considered the old version of flutter.bloc?


Solution

  • You can try if(event is LoginUsernameChanged){ instead of emit.

    But better is to call event LoginPasswordChanged which doesn't include on LoginBloc. This means you need to create a event class and register like on<LoginEvent>(event, emit):

    abstract class AuthEvent extends Equatable {
      const AuthEvent();
    
      @override
      List<Object> get props => [];
    }
    
    class LoginEvent extends AuthEvent {}
    
    class LoginUserNameCHanged extends AuthEvent {}
    
    
    class AuthBloc extends Bloc<AuthEvent, AuthState> {
      AuthBloc() : super(AuthInitial()) {
        on<LoginEvent>((event, emit) {}); //this isnt abstract class
    
        on<LoginUserNameCHanged>((event, emit) {});
      }
    }