Home > Back-end >  Is it correct to add event to Bloc in initState or didUpdateWidget?
Is it correct to add event to Bloc in initState or didUpdateWidget?

Time:10-20

Is it correct to add event to Bloc in initState or didChangeDependencies?

I tried to add event in initState and didChangeDependencies. But throw this exception.

But when this page opens again, everything work fine.

The following StateError was thrown building BlocBuilder<SlotsBloc, SlotsState>(dirty, dependencies: [_InheritedProviderScope<SlotsBloc?>], state: _BlocBuilderBaseState<SlotsBloc, SlotsState>#29045):
Bad state: No element

CodePudding user response:

I don't think this is how Bloc is intended to be used.

By reading a lot of examples on the official documentation, i see that the BlocProviders are always placed somewhere within the widget tree. This means that they are not accessible without a BuildContext, so you can't access them in initState or in didChangeDependencies.

Another problem with this approach is that you are letting the user interface dictate state changes, and it should be the opposite.

CodePudding user response:

you can do sth like this:

BlocProvider<SlotsBloc>(
      create: (context) => SlotsBloc()..add(SlotInitState()),
      child: child
)

CodePudding user response:

There's no problem calling in initState, it all depends on what you need. See in the example that I instantiated the bloc inside the statefull, called an event and passed it to BlocBuilder, with this you can use the bloc instance to add other events without having to read the context and at the same time I provide it to BlocBuilder, if you don't pass the bloc to BlocBuilder it will do the same thing you did in initState, run a BlocProvider.of<ExampleBloc>(context) to access the instance in context.

Observer this official example from the documentation, github_Search.

class MyHomeStatefull extends StatefulWidget {
  const MyHomeStatefull({Key? key}) : super(key: key);

  @override
  State<MyHomeStatefull> createState() => _MyHomeStatefullState();
}

class _MyHomeStatefullState extends State<MyHomeStatefull> {
  late ExampleBloc exampleBloc;
  @override
  void initState() {
    super.initState();

    // instance bloc and insert event
    exampleBloc = BlocProvider.of<ExampleBloc>(context)..add(StartEvent());

    //or

    //exampleBloc = context.read<ExampleBloc>()..add(StartEvent());
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Page')),
      body: BlocBuilder<ExampleBloc, ExampleState>(
        bloc: exampleBloc,
        builder: (context, state) {
          if (state.isLoading) {
            return const Center(child: CircularProgressIndicator());
          }
          return ListView(
            children: List.generate(
              state.listInterger.length,
              (index) => ListTile(
                title: Text('${state.listInterger[index]}'),
              ),
            ),
          );
        },
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: (){
          exampleBloc.add(OtherEvent());
        },
      ),
    );
  }
}
  • Related