Bloc: Cannot access state after migration to 6.0.1

Created on 7 Aug 2020  路  9Comments  路  Source: felangel/bloc

I've migrated my app to flutter_bloc: ^6.0.1 and now I'm getting exception The getter '...' was called on null. when trying to access state property.

To Reproduce
Once app is loaded it redirects user to LoginSignupPage. Here is the code of the page:

class LoginSignupPage extends StatelessWidget{
  final UserRepository _userRepository;

  LoginSignupPage({@required UserRepository userRepository})
    :assert (userRepository != null),
    _userRepository = userRepository;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: BlocProvider<LoginSignupBloc>(
        create: (context) => LoginSignupBloc(userRepository: _userRepository),
        child: LoginSignupForm(userRepository: _userRepository),
      ),
    );
  }
}

Then on LoginSignupForm I'm trying to show either Login or Register form depending on state parameter:

class LoginSignupForm extends StatefulWidget{
  final UserRepository _userRepository;

  LoginSignupForm({@required UserRepository userRepository})
    :assert (userRepository != null),
        _userRepository = userRepository;

  State<LoginSignupForm> createState() => _LoginSignupFormState();
}

class _LoginSignupFormState extends State<LoginSignupForm>{

  LoginSignupBloc _loginSignupBloc;

  UserRepository get _userRepository => widget._userRepository;

  @override
  void initState() {
    super.initState();
    _loginSignupBloc = BlocProvider.of<LoginSignupBloc>(context);    
  }

  @override
  Widget build(BuildContext context) {
    return BlocListener<LoginSignupBloc, LoginSignupState>(
      listener: (context, state){ 
        if(state.isLoginForm){
          this.linkText = "Don't have an account?";
          this.linkButtonText = "Create new";
          this.actionText = "Login";
        }
        if(state.isRegisterForm){
          this.linkText = "Already have an account?";
          this.linkButtonText = "Login";
          this.actionText = "Register";
        }    
      },
      child: BlocBuilder<LoginSignupBloc, LoginSignupState>(
        builder: (context, state){
          return Center(
            child: SingleChildScrollView(
              child: Container(                
                child: Column(
                  children: <Widget>[
                    _header(),
                    Container(
                      margin: const EdgeInsets.only(top: 40, left: 20, right: 20, bottom: 20),
                      child: Builder(
                        builder: (context) => Form(
                          key: _formKey,
                          child: Column(
                            children: <Widget>[                              
                              state.isRegisterForm ? _usernameTextField(_usernameController, state) : Container(height: 0, width: 0,),
                              !state.isPasswordReseted ?  _emailTextField(_emailController, state) : Container(height: 0, width: 0,),
                              _passwordResetInfo(state),
                              state.isLoginForm || state.isRegisterForm ? _passwordTextField(_passwordController, state) : Container(height: 0, width: 0,),
                              state.isLoginForm ? _forgotPasswordLink() : Container(height: 0, width: 0,),
                              _showErrorMessage(),
                              _progressIndicator(),
                              !state.isPasswordReseted ? _submitButton(state) : Container(height: 0, width: 0,),
                              _footerLink(state)
                            ], ), ),),)],),),));}),);}...}

I'm getting error on widget child: Builder :
The getter 'isRegisterForm' was called on null.
Receiver: null
Tried calling: isRegisterForm

Expected behavior
Worked fine on bloc version 4.0.0

question

Most helpful comment

@felangel Magic thing but it works fine after reinstallation 馃槂
Thanks for your prompt response and advise!

All 9 comments

Hi @YanaKrivitskaya 馃憤
Thanks for opening an issue!

I'm guessing this is because you didn't update the bloc to pass the initial state to super

LoginSignupBloc() : super(LoginSignupState());

Previously, you would provide the initial state via the initialState getter like:

@override
LoginSignupState get initialState => LoginSignupState();

but the initialState override has been removed and you must now provide the initial state to super. Let me know if that helps 馃憤

@felangel This is how my LoginSignupBloc looks like:

class LoginSignupBloc extends Bloc<LoginSignupEvent, LoginSignupState> {
  UserRepository _userRepository;

  LoginSignupBloc({@required UserRepository userRepository}) : assert (userRepository != null),
      _userRepository = userRepository, super(LoginSignupState.empty());

... }

And this is how it was initialized previously:

@override
  LoginSignupState get initialState => LoginSignupState.empty();

So I've added super(LoginSignupState.empty()) but the error persists.

@YanaKrivitskaya are you able to share a link to the project? If not can you provide the complete bloc and state implementations?

I just took a look and cloned the project and was not able to reproduce the issue 馃
What steps should I take to reproduce the error?

Simulator Screen Shot - iPhone SE (2nd generation) - 2020-08-07 at 15 27 27

@felangel Strange. I'm getting error right after app loads. Let me try to reinstall it...

Were you using code from branch TRC-52-...?

sounds good 馃憤
yup, I checked out the same branch and everything worked. If you're still seeing the error message me on discord and we can debug it live 馃槃

@felangel Magic thing but it works fine after reinstallation 馃槂
Thanks for your prompt response and advise!

Awesome, glad to hear it 馃槃

Was this page helpful?
0 / 5 - 0 ratings

Related issues

krusek picture krusek  路  3Comments

clicksocial picture clicksocial  路  3Comments

nerder picture nerder  路  3Comments

wheel1992 picture wheel1992  路  3Comments

hivesey picture hivesey  路  3Comments