coldasspirit
coldasspirit

Reputation: 127

how can i solve blocProvider context problem?

I have submit button, but when i press the button it gives this error:

BlocProvider.of() called with a context that does not contain a CreatePostCubit.
No ancestor could be found starting from the context that was passed to BlocProvider.of(). This can happen if the context you used comes from a widget above the BlocProvider. The context used was: Builder

I suppose contexts get mixed. how can i solve this error?

my code:

Widget createPostButton(BuildContext context) {
  final TextEditingController _postTitleController = TextEditingController();

  final TextEditingController _postDetailsController = TextEditingController();
  final TextEditingController _priceController = TextEditingController();

  final _formKey = GlobalKey<FormState>(debugLabel: '_formKey');
  return BlocProvider<CreatePostCubit>(
    create: (context) => CreatePostCubit(),
      child: Padding(
      padding: const EdgeInsets.only(right: 13.0, bottom: 13.0),
      child: FloatingActionButton(
        child: FaIcon(FontAwesomeIcons.plus),
        onPressed: () {
          showDialog(
              context: context,
              barrierDismissible: false,
              builder: (context) {
                return AlertDialog(
                  content: Form(
                    key: _formKey,
                    child: SingleChildScrollView(
                      child: Column(
                        mainAxisSize: MainAxisSize.min,
                        children: <Widget>[
                          Padding(
                              padding: EdgeInsets.all(8.0),
                              child: TextFormField(
                                autocorrect: true,
                                controller: _postTitleController,
                                textCapitalization: TextCapitalization.words,
                                enableSuggestions: false,
                                validator: (value) {
                                  if (value.isEmpty || value.length <= 4) {
                                    return 'Please enter at least 4 characters';
                                  } else {
                                    return null;
                                  }
                                },
                                decoration:
                                    InputDecoration(labelText: 'Post Title'),
                              )),
                          Padding(
                              padding: EdgeInsets.all(8.0),
                              child: TextFormField(
                                controller: _postDetailsController,
                                autocorrect: true,
                                textCapitalization: TextCapitalization.words,
                                enableSuggestions: false,
                                validator: (value) {
                                  if (value.isEmpty || value.length <= 25) {
                                    return 'Please enter at least 25 characters';
                                  } else {
                                    return null;
                                  }
                                },
                                decoration: InputDecoration(
                                    labelText: 'Write a post details'),
                              )),
                          Padding(
                              padding: EdgeInsets.all(8.0),
                              child: TextFormField(
                                controller: _priceController,
                                enableSuggestions: false,
                                inputFormatters: <TextInputFormatter>[
                                  FilteringTextInputFormatter.digitsOnly
                                ],
                                keyboardType: TextInputType.number,
                                validator: (value) {
                                  if (value.isEmpty || value.length >= 4) {
                                    return 'Please enter a valid value';
                                  } else {
                                    return null;
                                  }
                                },
                                decoration:
                                    InputDecoration(labelText: 'Enter the Price'),
                              )),
                          OutlinedButton(
                            style: OutlinedButton.styleFrom(
                              primary: Colors.white,
                              backgroundColor: Colors.blue,
                            ),
                            child: Text("Submit"),
                            onPressed: () => {
                              BlocProvider.of<CreatePostCubit>(context)
                                  .createNewPost(
                                      postTitle: _postTitleController.text,
                                      postDetails: _postDetailsController.text,
                                      price: _priceController.text)
                            },
                          ),
                        ],
                      ),
                    ),
                  ),
                );
              });
        },
      ),
    ),
  );
}

Upvotes: 1

Views: 562

Answers (3)

Moaid ALRazhy
Moaid ALRazhy

Reputation: 1744

I think the problem is that context in BlocProvider.of<CreatePostCubit>(context) refer to the orginal context which doesn't have cubit so try to rename the context into sth else like _context :

create: (_context) => CreatePostCubit(),

and when calling like this

 BlocProvider.of<CreatePostCubit>(_context)

Upvotes: 0

Adelina
Adelina

Reputation: 11871

Your showDialog builder is using new context. The widget returned by the builder does not share a context with the location that showDialog is originally called from.

Just rename builder parameter into something else

          showDialog(
              context: context,
              barrierDismissible: false,
              builder: (dialog_context) { // instead of context
                return AlertDialog(
                ....

Also you need to wrap BlocProvide child with builder(so it can access inherited BlocProvider)

BlocProvider<CreatePostCubit>(
    create: (context) => CreatePostCubit(),
    child: Builder(
        builder: (BuildContext context) => Padding(
        ...

Upvotes: 2

Nishuthan S
Nishuthan S

Reputation: 1735

Use BlocProvider.of<CreatePostCubit>(context,listen:false) instead of BlocProvider.of<CreatePostCubit>(context) in you submit button.

Upvotes: 0

Related Questions