Bloc: BlocProvider.of() called with a context that does not contain a Cubit of type.

Created on 1 Aug 2020  路  1Comment  路  Source: felangel/bloc

I have migrated to the flutter_bloc:^6.0.0 and started getting 'BlocProvider.of() called with a context that does not contain a Cubit of type.' error. Can you let me know what the problem is with the code?

I am adding the logs.

        No ancestor could be found starting from the context that was passed to BlocProvider.of<OtpGenerationBloc>().

        This can happen if the context you used comes from a widget above the BlocProvider.

        The context used was: OTPGenerationPage(dirty, dependencies: [MediaQuery], state: _OTPGenerationPageState#3e7df)

class OTPGenerationPage extends StatefulWidget {
  @override
  _OTPGenerationPageState createState() => _OTPGenerationPageState();
}

class _OTPGenerationPageState extends State<OTPGenerationPage> {
  final _formKey = GlobalKey<FormState>();

  bool _errorTextVisibility = false;
  String _errorText = '';
  OTPGenerationRequest generationRequest = OTPGenerationRequest();

  @override
  Widget build(BuildContext context) {
    MediaQueryUtils _mediaQueryUtils = MediaQueryUtils(context: context);
    return BlocProvider(
      create: (context) => OtpGenerationBloc(),
      child: PlatformScaffold(
        material: (context, platform) =>
            MaterialScaffoldData(resizeToAvoidBottomInset: false),
        body: BlocListener<OtpGenerationBloc, OtpGenerationState>(
          listenWhen: (previous, current) => previous != current,
          listener: (context, state) {
            if (state is OtpGenerated) {
              String _data = state.otpResponse.toJson().toString();
              print(_data);
              Navigator.pushNamed(context, Routing.SamplePageRoute,
                  arguments: RouteDataModel(
                      data: _data, animationType: SlideAnimationType.LEFT));
            }
          },
          cubit: OtpGenerationBloc(),
          child: Column(
          children: [
                 Container(
                      width: _mediaQueryUtils.deviceSize.width,
                      height: 50,
                      margin: EdgeInsets.fromLTRB(15, 0, 15, 0),
                      child: PlatformButton(
                          color: Colors.black,
                          child: PlatformText(
                            'NEXT',
                            style: TextStyle(color: Colors.white),
                          ),
                          onPressed: () {
                            if (_formKey.currentState.validate()) {
                              _formKey.currentState.save();
                              setState(() {
                                String _countryCodeValidationString =
                                    generationRequest.validateCountryCode();
                                String _phoneNumberValidationString =
                                    generationRequest.validatePhoneNumber();
                                if (_countryCodeValidationString != null) {
                                  _errorText = _countryCodeValidationString;
                                  _errorTextVisibility = true;
                                } else if (_phoneNumberValidationString !=
                                    null) {
                                  _errorText = _phoneNumberValidationString;
                                  _errorTextVisibility = true;
                                } else {
                                  _errorTextVisibility = false;
                                  context.bloc<OtpGenerationBloc>().add(
                                      GenerateOTP(
                                          otpGenerationRequest:
                                              generationRequest));
                                }
                              });
                            }
                          }),
                    ),
          ]);
question

Most helpful comment

Hi @jaydangar 馃憢
Thanks for opening an issue!

The problem isn't specific to v6.0.0 -- in general you cannot access a bloc via the same BuildContext in which it was provided. If you want to do this you have to wrap your PlatformButton in a Builder widget to get a new BuildContext which will contain the OtpGenerationBloc

Builder(
  builder: (context) {
    return PlatformButton(
      onPressed: () {
        context.bloc<OtpGenerationBloc>().add(...);
      },
      ...
    );
  },
)

Generally you should separate the widget which is providing the bloc from the widget which is consuming the bloc in order to make your code more testable.

Hope that helps and closing this for now 馃憤

>All comments

Hi @jaydangar 馃憢
Thanks for opening an issue!

The problem isn't specific to v6.0.0 -- in general you cannot access a bloc via the same BuildContext in which it was provided. If you want to do this you have to wrap your PlatformButton in a Builder widget to get a new BuildContext which will contain the OtpGenerationBloc

Builder(
  builder: (context) {
    return PlatformButton(
      onPressed: () {
        context.bloc<OtpGenerationBloc>().add(...);
      },
      ...
    );
  },
)

Generally you should separate the widget which is providing the bloc from the widget which is consuming the bloc in order to make your code more testable.

Hope that helps and closing this for now 馃憤

Was this page helpful?
0 / 5 - 0 ratings