Search code examples
flutterdartbloc

In ListView.builder Bloc event triggered only once


enter image description hereenter image description hereI m using Bloc for state management , I have my screen where I'm calling event in ListView.builder

   loadSuccess: (state) {
        return ListView.builder(
            shrinkWrap: true,
            physics: const NeverScrollableScrollPhysics(),
            itemCount: state.questions.size,
            itemBuilder: (
              context,
              index,
            ) {
              // ignore: avoid_unnecessary_containers

              debugPrint("this is index $index");
              debugPrint(
                  "this is user id ${state.questions.get(index).userId.getorCrash()}");

              context.read<UsersWatcherBloc>().add(
                    UsersWatcherEvent.watchAllUsers(
                      state.questions.get(index).userId.getorCrash(),
                    ),
                  );
              return Container(
                color: Colors.white,
                 ......)

But problem is that my event is triggered only one time and state changed one time but I want to change my event for each index :

Event.dart:

    part of 'users_watcher_bloc.dart';

   @freezed
    abstract class UsersWatcherEvent with _$UsersWatcherEvent {
    const factory UsersWatcherEvent.watchAllUsers(String uId) = _Started;
      }

Bloc.dart:

      @injectable
    class UsersWatcherBloc extends Bloc<UsersWatcherEvent, UsersWatcherState> {
   final IElearningRepository _iElearningRepository;

    UsersWatcherBloc(this._iElearningRepository)
  : super(const UsersWatcherState.initial());

    @override
   Stream<UsersWatcherState> mapEventToState(
   UsersWatcherEvent event,
 ) async* {
  yield* event.map(
  watchAllUsers: (e) async* {
    print("this is user id ${e.uId}");
    yield const UsersWatcherState.loadInProgress();
    yield* _iElearningRepository.watchAllUsers(e.uId.toString()).map(
          (failureOrUsers) => failureOrUsers.fold(
            (f) => UsersWatcherState.loadFailure(f),
            (users) {
              if (users.isEmpty) {
                return const UsersWatcherState.empty();
              }

              return UsersWatcherState.loadSuccess(users);
            },
          ),
        );
  },
);
 }
   }

Solution

  • After 2 days struggle I found solution of this question, I have to wrap my container with another BlocProvider and use dependency injection

      loadSuccess: (state) {
            return ListView.builder(
              shrinkWrap: true,
              physics: const NeverScrollableScrollPhysics(),
              itemCount: state.questions.size,
              itemBuilder: (
                context,
                index,
              ) {
                // ignore: avoid_unnecessar_containers
    
                return BlocProvider(
                  create: (context) => getIt<UsersWatcherBloc>()
                    ..add(
                      UsersWatcherEvent.watchCurrentUser(
                        state.questions.get(index).userId.getorCrash(),
                      ),
                    ),
                  child: Container(
                    color: Colors.white,
                    margin: const EdgeInsets.only(bottom: 5),
                    padding: EdgeInsets.only(
                      left: leftPadding.w - 8.w,
                      right: rightpadding.w - 8.w,
                      bottom: bottomPadding.h,
                    ),
                    child: Column(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: [