skip to Main Content

I have a piece of code where i need to call two bloc events sequentially the issue is that the first event is fired and api is called but the second is not being called , i tried to debug my code and i came to the conclusion that if i call both events from different blocs , they both get fired but if from the same bloc .. only the first gets fired , any help would be appreciate guys . Thank you

  • This is my code ( check initState , calling two events from same bloc )

 class _FurniturePageState extends State<FurniturePage> {
  String userImage = "";
  final List<String> _titles = ["Lamp","Chair","Table","Sofa","Bed"];
  final List<String> _images = [
    "assets/images/lamp.png",
    "assets/images/chair.png",
    "assets/images/table.png",
    "assets/images/sofa.png",
    "assets/images/bed.png"
  ];
  late int selectedCategory = 0;

  @override
  void initState() {
    super.initState();
    BlocProvider.of<ShopBloc>(context).add(GetUserDataEvent());
    BlocProvider.of<ShopBloc>(context).add(GetFurnitureEvent("Lamp"));
  }
  
  @override
  Widget build(BuildContext context) {
    return BlocListener<ShopBloc,ShopBlocState>(
        listener: (context,state){
           if(state is GetUserDataState){
              setState(() {
                 userImage =  state.userModel.userImage!;
              });
              StorageHelper.saveInfo(state.userModel.name!, state.userModel.email!, state.userModel.phone!);
           }
        },
        child: SingleChildScrollView(
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              Padding(
                padding: const EdgeInsets.all(20),
                child: Row(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    Expanded(child:  Column(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: [
                        Text(_setDayTime(),style: getArimoBold().copyWith(fontSize: 34),),
                        Text("Welcome back",style: getArimoRegular().copyWith(fontSize: 20),)
                      ],
                    )),
                    GestureDetector(
                      onTap: (){
                        Get.toNamed(Utils.cartRoute);
                      },
                      child : Container(
                        width: 45,
                        height: 45,
                        decoration: BoxDecoration(
                            borderRadius: BorderRadius.circular(60),
                            color: Colors.grey.shade200
                        ),
                        child: const Center(child: Icon(Icons.add_shopping_cart,size: 20,),),
                      ),
                    ),
                    const Gap(10),
                    Center(
                      child: CircleAvatar(
                        radius: 20,
                        foregroundImage: NetworkImage(userImage),
                      ),
                    ),
                  ],
                ),
              ),
              Padding(
                padding: const EdgeInsets.all(15),
                child: ClipRRect(
                  borderRadius: BorderRadius.circular(8),
                  child: Image.asset("assets/images/banner.png",fit: BoxFit.cover,
                    height: 200,width: double.maxFinite,),
                ),
              ),
              Padding(
                padding: const EdgeInsets.only(left: 25,right: 20,top: 20),
                child: Row(
                  children: [
                    Expanded(flex: 2,child: Text("Choose Category",style: getArimoBold().copyWith(fontSize: 25),),),
                    Expanded(child: GestureDetector(
                      onTap: (){
                        Get.toNamed(Utils.viewAllRoute);
                      },
                      child: Text("View All",style: getArimoRegular().copyWith(fontSize: 18),
                        textAlign: TextAlign.end,),
                    ))
                  ],
                ),
              ),
              Padding(
                padding: const EdgeInsets.all(15),
                child: SizedBox(
                  height: 130,
                  child: ListView.builder(
                    shrinkWrap: true,
                    itemCount: _titles.length,
                    scrollDirection: Axis.horizontal,
                    itemBuilder: (context,index){
                      return Padding(
                        padding: const EdgeInsets.all(10),
                        child: GestureDetector(
                          onTap: (){
                            setState(() {
                              selectedCategory = index;
                            });
                            BlocProvider.of<FurnitureBloc>(context).add(GetFurnitureEvent(_titles[index]));
                          },
                          child: Column(
                            children: [
                              Container(
                                width: 70,
                                height: 70,
                                decoration:  BoxDecoration(
                                  borderRadius: BorderRadius.circular(60),
                                  color: selectedCategory == index ? Colors.black : Colors.grey.shade200,
                                ),
                                child: Center(child: Image.asset(_images[index],filterQuality: FilterQuality.high,
                                  width: 40,height: 40,color: Colors.grey.shade500,),),
                              ),
                              const SizedBox(height: 5,),
                              Center(child: Text(_titles[index],style: getArimoRegular().copyWith(fontSize: 16),),)
                            ],
                          ),
                        ),
                      );
                    },
                  ),
                ),
              ),
              Padding(
                padding: const EdgeInsets.only(left: 15,right: 15),
                child: BlocBuilder<FurnitureBloc,ShopBlocState>(
                  builder: (context,state){
                    if(state is LOADING){
                      return const Center(child: CircularProgressIndicator(),);
                    }
                    else if (state is ERROR){
                      return SizedBox(
                        width: MediaQuery.of(context).size.width,
                        height: MediaQuery.of(context).size.height / 3,
                        child: Center(
                          child: Text(state.e.toString(),style: getArimoBold().copyWith(fontSize: 20),),
                        ),
                      );
                    }
                    else if(state is GetFurnitureState){
                      var data = state.furniture;
                      if(data.isNotEmpty){
                        return GridView.builder(
                          physics: const NeverScrollableScrollPhysics(),
                          shrinkWrap: true,
                          itemCount: data.length,
                          scrollDirection: Axis.vertical,
                          gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
                            crossAxisCount: 2,
                            mainAxisSpacing: 10,
                            crossAxisSpacing: 10,
                            childAspectRatio: 0.8, // Adjust the aspect ratio to ensure cards are not too tall
                          ),
                          itemBuilder: (context, index) {
                            return Card(
                              margin: const EdgeInsets.all(10),
                              color: Colors.grey.shade200,
                              child: Column(
                                crossAxisAlignment: CrossAxisAlignment.start,
                                children: [
                                  Flexible(
                                    child:  ClipRRect(
                                      borderRadius: BorderRadius.circular(16),
                                      child: CachedNetworkImage(
                                        imageUrl : data[index]!.image!,
                                        placeholder: (context, url) => Image.asset("assets/images/no_image.png"),
                                        width : double.maxFinite,
                                        height: 180,
                                        fit: BoxFit.cover,
                                        filterQuality: FilterQuality.high,
                                        fadeInDuration: const Duration(milliseconds: 500),
                                      ),
                                    ),
                                  ),
                                  Padding(
                                    padding: const EdgeInsets.all(8.0),
                                    child: Row(
                                      crossAxisAlignment: CrossAxisAlignment.start,
                                      children: [
                                        Expanded(
                                            child:  Column(
                                              crossAxisAlignment: CrossAxisAlignment.start,
                                              children: [
                                                Text(
                                                  data[index]!.title!,
                                                  style: getArimoBold().copyWith(fontSize: 15),
                                                  maxLines: 1,
                                                  overflow: TextOverflow.ellipsis,
                                                ),
                                                Text(
                                                  "${data[index]!.price}$",
                                                  style: getArimoRegular().copyWith(fontSize: 15),
                                                ),
                                              ],
                                            )),
                                        Align(
                                          alignment: Alignment.centerRight,
                                          child: SizedBox(
                                            width: 40,
                                            height: 40,
                                            child: GestureDetector(
                                              onTap: () {
                                                StorageHelper.setPosition(0);
                                                Get.toNamed(Utils.detailsRoute,arguments:data[index]?.id!);
                                              },
                                              child: Card(
                                                shape: RoundedRectangleBorder(
                                                  borderRadius: BorderRadius.circular(16),
                                                ),
                                                child: Center(
                                                  child: Image.asset(
                                                    "assets/images/arrow.png",
                                                    width: 15,
                                                    height: 15,
                                                  ),
                                                ),
                                              ),
                                            ),
                                          ),
                                        ),
                                      ],
                                    ),
                                  ),
                                ],
                              ),
                            );
                          },
                        );
                      }
                      else {
                        return SizedBox(
                          width: MediaQuery.of(context).size.width,
                          height: MediaQuery.of(context).size.height / 3,
                          child: Center(
                            child: Text("No Furniture Found",style: getArimoBold().copyWith(fontSize: 20),),
                          ),
                        );
                      }
                    }
                    else {
                      return SizedBox(
                        width: MediaQuery.of(context).size.width,
                        height: MediaQuery.of(context).size.height / 3,
                        child: Center(
                          child: Text("No Furniture Found",style: getArimoBold().copyWith(fontSize: 20),),
                        ),
                      );
                    }
                  },
                ),
              )
            ],
          ),
        ),);
  }
  String _setDayTime(){
    DateFormat dateFormat = DateFormat("hh a");
    DateTime dateTime = DateTime.now();
    String formattedString = dateFormat.format(dateTime);
    if(formattedString.contains("AM")){
      return "Good Morning";
    } else {
      return "Good Evening";
    }
  }

}

2

Answers


  1. It depends on how you have declared events consumption inside constructor of Bloc. If you are using same ‘on’, events will be consumed one after another but if you have different ‘on’, they should arrive in parallel.

    Sample code

    import 'package:equatable/equatable.dart';
    import 'package:flutter/material.dart';
    import 'package:flutter_bloc/flutter_bloc.dart';
    
    final Stopwatch _stopwatch = Stopwatch();
    void main() {
      WidgetsFlutterBinding.ensureInitialized();
      _stopwatch.start();
      runApp(const MyApp());
    }
    
    class MyApp extends StatelessWidget {
      const MyApp({super.key});
    
      @override
      Widget build(BuildContext context) {
        return BlocProvider(
          create: (_) => MyBloc(),
          child: MaterialApp(
            title: 'Flutter Demo',
            theme: ThemeData(
              colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
              useMaterial3: true,
            ),
            home: const MyHomePage(),
          ),
        );
      }
    }
    
    class MyHomePage extends StatefulWidget {
      const MyHomePage({super.key});
    
      @override
      State<MyHomePage> createState() => _MyHomePageState();
    }
    
    class _MyHomePageState extends State<MyHomePage> {
      @override
      void initState() {
        super.initState();
        context.read<MyBloc>().add(const FirstEvent());
        context.read<MyBloc>().add(const SecondEvent());
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: const Text('Demo'),
          ),
          body: Center(
            child: BlocConsumer<MyBloc, MyState>(builder: (context, state) {
              return switch (state) {
                Uninitialized() => const Text('Uninitialized'),
                Loading() => const Text('Loading'),
                Loaded() => Text(state.data),
                Failed() => Text(state.error),
              };
            }, listener: (context, state) {
              String msg = state.toString();
              printMsg(msg);
            }),
          ),
        );
      }
    }
    
    void printMsg(String msg) {
      print('${_stopwatch.elapsedMilliseconds}ms: $msg ');
    }
    
    class MyBloc extends Bloc<MyEvent, MyState> {
      MyBloc() : super(const Uninitialized()) {
        on<FirstEvent>((event, emit) async {
          printMsg('processing first event');
          emit(const Loading());
          await Future.delayed(const Duration(seconds: 5));
          emit(const Loaded('First data'));
        });
    
        on<SecondEvent>((event, emit) async {
          printMsg('processing second event');
          emit(const Loading());
          await Future.delayed(const Duration(seconds: 10));
          emit(const Loaded('Second data'));
        });
      }
    }
    
    @immutable
    sealed class MyEvent extends Equatable {
      const MyEvent();
    
      @override
      List<Object?> get props => [];
    }
    
    class FirstEvent extends MyEvent {
      const FirstEvent();
    }
    
    class SecondEvent extends MyEvent {
      const SecondEvent();
    }
    
    sealed class MyState extends Equatable {
      const MyState();
    
      @override
      List<Object?> get props => [];
    
      @override
      bool? get stringify => true;
    }
    
    class Uninitialized extends MyState {
      const Uninitialized();
    }
    
    class Loading extends MyState {
      const Loading();
    }
    
    class Loaded extends MyState {
      final String data;
      const Loaded(this.data);
    
      @override
      List<Object?> get props => [data];
    }
    
    class Failed extends MyState {
      final String error;
      const Failed(this.error);
    
      @override
      List<Object?> get props => [error];
    }
    
    

    dependencies used

    flutter_bloc: ^8.1.6
    meta: ^1.15.0
    equatable: ^2.0.5
    

    Sample output

    126ms: processing first event
    128ms: Loading()
    128ms: processing second event
    5136ms: Loaded(First data)
    10138ms: Loaded(Second data)
    
    Login or Signup to reply.
  2. First, I suggest to read about Dart Concurrency and Bloc Docs again, and then take look at this package and more details about Bloc Transformers on this article

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search