Search code examples
flutterbloc

How to use bloc with show Dialog flutter


this is my error :currently, I have an IconButton in the appbar of ListScreen. But when I click on it, it show up an error that do not recognize bloc in widget tree ? what can i do.

home page file:

class Home extends StatelessWidget {
  const Home({Key? key}) : super(key: key);
  @override
  Widget build(BuildContext context) {
    return RepositoryProvider(
      create: (context) => GateInBloc(),
      child: const HomeWidget(),
    );
  }
... body part:
          GestureDetector(
              onTap: () {
                var bloc = context.read<GateInBloc>();
                Navigator.of(context)
                    .pushNamed(MyPath.gatein, arguments: {'bloc': bloc});
              },
              child: const ItemCard(
                  assetLink: 'assets/images/GateIn.png',
                  text: 'Container GateIn'),
            ),

here is my Route:

    case MyPath.gatein:
      var bloc =
          (settings.arguments as Map<String, dynamic>)['bloc'] as GateInBloc;
      return MaterialPageRoute(
        builder: (context) => BlocProvider.value(
          value: bloc,
          child: const ListGateInScreen(),
        ),
      );

List Screen :


class ListGateInScreen extends StatefulWidget {
  const ListGateInScreen({super.key});

  @override
  State<ListGateInScreen> createState() => _ListGateInScreenState();
}

class _ListGateInScreenState extends State<ListGateInScreen> {
  var tuNgayController = TextEditingController();
  var denNgayController = TextEditingController();
  var soContainerController = TextEditingController();
  DateTime? TuNgay, DenNgay;

  @override
  void initState() {
    context.read<GateInBloc>().add(FetchInitEvent());
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: const Text('List GateIn'),
          actions: [
            Row(
              children: [
                IconButton(
                    onPressed: () {
                      context.read<GateInBloc>().add(FetchInitEvent());
                    },
                    icon: const Icon(Icons.replay_outlined)),
                BlocProvider.value(
                  value: context.read<GateInBloc>(),
                  child: IconButton(
                      onPressed: () {
                        showDialog(
                          context: context,
                          barrierDismissible: false, // user must tap button!
                          builder: (BuildContext context) {
                            tuNgayController.text =
                                DateFormat('dd/MM/yyyy').format(DateTime.now());
                            denNgayController.text =
                                DateFormat('dd/MM/yyyy').format(DateTime.now());
                            return BlocProvider.value(
                              value: context.read<GateInBloc>(),
                              child: BlocBuilder<GateInBloc, GateInState>(
                                builder: (context, state) {
                                  return DayPickerAleart(
                                      tuNgay: TuNgay,
                                      tuNgayController: tuNgayController,
                                      denNgay: DenNgay,
                                      denNgayController: denNgayController,
                                      soContainerController:
                                          soContainerController);
                                },
                              ),
                            );
                          },
                        );
                      },
                      icon: const Icon(Icons.search)),
                ),
              ],
            )
          ],
        ),

What wrong with my code, in the body part of List Screen I can use ConsumerBloc to recive data in normal ways, but can't figured out even have search for solution


Solution

  • try this:

     @override
      Widget build(BuildContext context) {
       /// set local variable to avoid retrieving bloc from dialog context for 
       /// BlocProvider.value
        final gateInBloc = context.read<GateInBloc>();
        return Scaffold(
            appBar: AppBar(
              title: const Text('List GateIn'),
              actions: [
                Row(
                  children: [
                    IconButton(
                        onPressed: () {
                          gateInBloc.add(FetchInitEvent());
                        },
                        icon: const Icon(Icons.replay_outlined)),
                    BlocProvider.value(
                      value: gateInBloc,
                      child: IconButton(
                          onPressed: () {
                            showDialog(
                              context: context,
                              barrierDismissible: false, // user must tap button!
                              builder: (BuildContext context) {
                                tuNgayController.text =
                                    DateFormat('dd/MM/yyyy').format(DateTime.now());
                                denNgayController.text =
                                    DateFormat('dd/MM/yyyy').format(DateTime.now());
                                return BlocProvider.value(
                                  value: gateInBloc,// here
                                  child: BlocBuilder<GateInBloc, GateInState>(
                                    builder: (context, state) {
                                      return DayPickerAleart(
                                          tuNgay: TuNgay,
        ...