Flutter Bloc listening the same state twice In TabView Page

31 Views Asked by At

This The Bloc Provider..

class PaymentHistoryScreen extends StatefulWidget {
      static const String routeName = '/payment-history';
    
      PaymentHistoryScreen({super.key, required this.hospitalNumber});
      final String hospitalNumber;
    
      @override
      State<PaymentHistoryScreen> createState() => _PaymentHistoryScreenState();
    }
    
    class _PaymentHistoryScreenState extends State<PaymentHistoryScreen> {
      final GlobalKey<NavigatorState> navigatorKey = GlobalKey();
    
      @override
      Widget build(BuildContext context) {
        return MultiBlocProvider(
          providers: [
            BlocProvider(
              create: (context) => PaymentHistoryBloc(getService()),
              // ..add(
              //   PaymentHistoryGet(
              //     hospitalNumber: widget.hospitalNumber,
              //   ),
              // ),
            ),
            BlocProvider(
              create: (context) => InvoiceDetailsBloc(getService()),
            ),
            BlocProvider(
              create: (context) =>
                  CompanyLocationBloc(getService())..add(CompanyLocationsGet()),
            ),
          ],
          child: PaymentHistoryScreenTop(
            hospitalNumber: widget.hospitalNumber,
          ),
        );
      }
    }

TabBar Controller..

class PaymentHistoryScreenBodyState extends State<PaymentHistoryScreenBody>
    with TickerProviderStateMixin {
  late TabController tabviewController;

  @override
  void initState() {
    super.initState();
    tabviewController = TabController(
      length: 3,
      vsync: this,
      initialIndex: 0,
    );

TabBarView..

 Expanded(
                    child: SizedBox(
                      height: 408.v,
                      child: TabBarView(
                        controller: tabviewController,
                        children: [
                          PaymentHistoryTab(
                            paymentHistories: state.diagnosisList,
                          ),
                          PaymentHistoryTab(
                            paymentHistories: state.consultList,
                          ),
                          PaymentHistoryTab(
                            paymentHistories: state.pharmacyList,
                          ),
                        ],
                      ),
                    ),
                  ),

Bloc Code...

sealed class InvoiceDetailsEvent {}

final class InvoiceDetailsGet extends InvoiceDetailsEvent {
  final String invoiceId;
  final int billModuleNo;

  InvoiceDetailsGet({required this.invoiceId, required this.billModuleNo});
}

sealed class InvoiceDetailsState {}

final class InvoiceDetailsInitial extends InvoiceDetailsState {}

final class InvoiceDetailsLoading extends InvoiceDetailsState {}

final class InvoiceDetailsSuccess extends InvoiceDetailsState {
  final List<ItemDtls> response;

  InvoiceDetailsSuccess({required this.response});
}

final class InvoiceDetailsError extends InvoiceDetailsState {
  final Object error;

  InvoiceDetailsError({required this.error});
}

class InvoiceDetailsBloc
    extends Bloc<InvoiceDetailsEvent, InvoiceDetailsState> {
  final DataRepository _dataRepository;
  InvoiceDetailsBloc(this._dataRepository) : super(InvoiceDetailsInitial()) {
    on<InvoiceDetailsGet>((event, emit) async {
      emit(InvoiceDetailsLoading());
      try {
        var response = await _dataRepository.getInvoiceDetailsByInvoiceId(
            invoiceId: event.invoiceId, billModuleNo: event.billModuleNo);
        if (response.isNotEmpty) {
          emit(InvoiceDetailsSuccess(response: response));
        } else {
          throw CustomException("No data found for this invoice");
        }
      } catch (e) {
        emit(InvoiceDetailsError(error: e));
      }
    });
  }
}

calling the bloc in this page

// ignore: must_be_immutable
class InvoicedetailslistItemWidget extends StatelessWidget {
  const InvoicedetailslistItemWidget({Key? key, required this.item})
      : super(
          key: key,
        );

  final InvoiceItem item;


  @override
  Widget build(BuildContext context) {
    return Container(
      padding: EdgeInsets.symmetric(horizontal: 6.v, vertical: 14.h),
      decoration: AppDecoration.fillCyan,
      child: Row(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          Container(
            height: 50.adaptSize,
            width: 50.adaptSize,
            decoration: AppDecoration.fillBlueGray,
            child: CustomImageView(
              svgPath: ImageConstant.imgThumbsUpPrimary,
              height: 50.adaptSize,
              width: 50.adaptSize,
              alignment: Alignment.center,
            ),
          ),
          Padding(
            padding: EdgeInsets.only(left: 13.h),
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                Text(
                  "INVOICE ID: ${item.invoiceId ?? "N/A"}",
                  style: CustomTextStyles.bodySmallBlack900,
                  overflow: TextOverflow.ellipsis,
                ),
                SizedBox(height: 5.v),
                Text(
                  "Date: ${item.invoiceDate?.toFormattedString("dd MMM yyyy") ?? "N/A"}",
                  style: CustomTextStyles.bodySmallBluegray300,
                ),
                SizedBox(height: 5.v),
                Text(
                  "Time: ${item.invoiceDateTime?.toFormattedString("hh:mm a").toLowerCase() ?? "N/A"}",
                  style: CustomTextStyles.bodySmallBluegray300,
                ),
              ],
            ),
          ),
          BlocListener<InvoiceDetailsBloc, InvoiceDetailsState>(
            listener: (context, state) async {
              if (state is InvoiceDetailsSuccess) {
                
                context.pushNamed(
                  ReportViewScreen.routeName,
                  extra: {"report": item, "data": data},
                );
              }
              if (state is InvoiceDetailsError) {
                ScaffoldMessenger.of(context).showSnackBar(
                  SnackBar(
                    content: Text(state.error.toString()),
                  ),
                );
              }
            },
            child: CustomOutlinedButton(
              onPressed: () async {
                BlocProvider.of<InvoiceDetailsBloc>(context).add(
                    InvoiceDetailsGet(
                        invoiceId: item.invoiceId!, billModuleNo: 1));
              },
              height: 38.v,
              width: 70.h,
              text: "View ",
              margin: EdgeInsets.only(
                left: 22.h,
                top: 11.v,
                bottom: 11.v,
              ),
              buttonStyle: CustomButtonStyles.outlinePinkTL6,
              buttonTextStyle: CustomTextStyles.labelLargePrimary,
            ),
          ),
        ],
      ),
    );
  }
}

Here i am the calling the bloc event single time but the bloc listener listening the same success sate twice and due to that navigating the same screen twice. i am unable to debug why bloc is triggering the same state twice. how to solve this.??? note: 1.the page is under a tabbarview. 2. Also InvoicedetailslistItemWidget is building with listview builder.

0

There are 0 best solutions below