skip to Main Content

here is the bloc class code , and here i added an event called NavItemVisibilityEvent
but when i call this event in another class the ui is not updating what’s the issue inside this code.

class MainScreenBloc extends Bloc<MainScreenEvent, MainScreenState> {

  MainScreenBloc() : super( MainScreenInitial(itemVisibility: itemVisibility)) {

    on<NavigationLoadedEvent>((event,emit)async{
      print('inside loaded Event');
      List<bool>? loadedBoolList = await PrefManager.loadBoolList('navBarList');
       if(loadedBoolList == null)
         {
           print('inside loadedBoolList');
           emit(MainScreenInitial(itemVisibility: itemVisibility));
           emit(MainScreenLoadedState(currentIndex: 0,itemVisibility:itemVisibility,visible: true));
           // emit(MainScreenInitial(itemVisibility: itemVisibility));
         }else{
         print('after pref loaded Event');
         print('loadedBoolList $loadedBoolList');
         emit(MainScreenInitial(itemVisibility: loadedBoolList));
         emit(MainScreenLoadedState(currentIndex: 0,itemVisibility:loadedBoolList,visible: true));
       }

    });
    on<NavigationEvent>((event, emit) async{
         final currentState = state as MainScreenLoadedState;
      // List<bool> loadedBoolList = await PrefManager.loadBoolList('navBarList');
      //  print('loadedBoolList $loadedBoolList');
      emit(MainScreenLoadedState(currentIndex: event.currentIndex,
          itemVisibility: currentState.itemVisibility,visible: true
      ));
       // print('navList $navList');
       // if(navList == null)
       //   {
       //     navList = await PrefManager.loadBoolList('navBarList')??itemVisibility;
       //
       //   }else{
       //   navList = await PrefManager.loadBoolList('navBarList')??itemVisibility;
       //   emit(MainScreenState(currentIndex: event.currentIndex,
       //       itemVisibility:navList
       //   ));
       // }

    });
    on<NavigationHideEvent>((event,emit) {
      final currentState = state as MainScreenLoadedState;
      emit(MainScreenLoadedState(currentIndex: currentState.currentIndex,visible: event.visible,
          itemVisibility:currentState.itemVisibility));
    });

    on<NavItemVisibilityEvent>((event,emit) async {
      final currentState = state as MainScreenLoadedState;
      print('inside event visibility');
      emit(MainScreenLoadedState(currentIndex: currentState.currentIndex, itemVisibility:event.itemVisibility,
          visible: true));
       print('final event visibility ${event.itemVisibility}');
      await PrefManager.saveBoolList(event.itemVisibility!,'navBarList');
    });

  }
}

here’s the state class code

class MainScreenState {
   MainScreenState();
}

class MainScreenInitial extends MainScreenState {
  List<bool>? itemVisibility;
  MainScreenInitial({this.itemVisibility});
}
class MainScreenLoadedState extends MainScreenState{
  final int? currentIndex;
  final bool? visible;
  List<bool>? itemVisibility;
  MainScreenLoadedState({this.currentIndex, this.visible,this.itemVisibility});

}

here is the another bloc class i want to access the state variable of mainbloc class and when i call the NavItemVisibilityEvent inside this call its not updating the current ui.

for (var i in state.toggleFavStates) {
                          switch (i.key) {
                            case 'Chat':
                              print('iteration');
                              final state = mainScreenBloc.state;
                              print('state $state');
                              if(state is  MainScreenInitial)
                                {
                                  print('state value ${state.itemVisibility}');
                                  print('itemVisibility');
                                  navList = state.itemVisibility;
                                  print('navList $navList');
                                }
                              print('naVlistss: $navList');
                              navList?[1] = i.value;
                              context.read<MainScreenBloc>().add
                                (NavItemVisibilityEvent(
                                  key: i.key,
                                  singleItem: i.value,
                                  itemVisibility:navList));
                              //do this to that index.
                              break;
                            case 'Schedule':
                              // navList =  mainScreenBloc.state.itemVisibility;
                              navList?[2] = i.value;
                              context.read<MainScreenBloc>().add
                                (NavItemVisibilityEvent(
                                  key: i.key,
                                  singleItem: i.value,
                                  itemVisibility:navList));
                              break;
                            case 'Profile':
                              // navList =  mainScreenBloc.state.itemVisibility;
                              navList?[3] = i.value;
                              context.read<MainScreenBloc>().add
                                (NavItemVisibilityEvent(
                                  key: i.key,
                                  singleItem: i.value,
                                  itemVisibility:navList));
                              break;
  
                           default:
                        
                              break;
                          }
                        }


here in this above screen i am calling

                    ```
                       context.read<MainScreenBloc>().add
                             (NavItemVisibilityEvent(
                              key: i.key,
                              singleItem: i.value,
                              itemVisibility:navList));

                                                   ```

but its not updating the my ui state.
and also here iam using the code to access the mainScreenLoaded state variable value & is this the right way to access the state variable value from another Bloc screen class.

                    ``` 
                          final state = mainScreenBloc.state;
                          print('state $state');
                          if(state is  MainScreenInitial)
                            {
                              print('state value ${state.itemVisibility}');
                              print('itemVisibility');
                              navList = state.itemVisibility;
                              print('navList $navList');
                            }

                            
                         ```

2

Answers


  1. I’m not sure I got the entire context from question but as general rule of thumb, for bloc please make sure check these things ->

    1. You have overridden hashcode and equal to operator in the state’s and the custom models inside the state. I generally use https://pub.dev/packages/equatable package for ease of code for this.
    2. Whenever you are trying to update a list item in state, firstly create a new list and then modify it and emit that. Also create copyWith methods and use that if you want to emit same state with different properties.
    List newList = List.from(state.myList)
    newList[index] = xyz
    emit(state.copyWith(newList)
    
    1. If you want the UI to be updated as soon as a new state is emited, make sure you use the BlocBuilder widet and have written the code inside that.
    2. Make sure that scope of bloc is either global, i.e written in your main app or else is at least provided to new screen when you push the new screen. You can do that using
     Navigator.of(context).push(
          MaterialPageRoute(
            builder: (_) => BlocProvider.value(
              value: BlocProvider.of<BlocX>(context),
              child: Screen2(),
            ),
          ),
        );
        ```
    
    Login or Signup to reply.
  2. The issue with your code is that you are not emitting a new state when you call the NavItemVisibilityEvent. In order for the UI to update, you need to emit a new state that reflects the change in the itemVisibility variable.

    To fix this issue, you can simply emit a new MainScreenLoadedState with the updated itemVisibility variable. For example:

    context.read<MainScreenBloc>().add(
      NavItemVisibilityEvent(
        key: i.key,
        singleItem: i.value,
        itemVisibility: navList,
      ),
    );
    
    emit(MainScreenLoadedState(
      currentIndex: currentState.currentIndex,
      itemVisibility: navList,
      visible: true,
    ));
    

    This will ensure that the UI is updated with the new itemVisibility variable.

    As for accessing the state variable of the MainScreenBloc from another bloc class, this is perfectly fine to do. To do this, you can simply use the context.read<MainScreenBloc>() method. This will return a reference to the MainScreenBloc instance.

    Here is an example of how to do this:

    final state = context.read<MainScreenBloc>().state;
    
    if (state is MainScreenLoadedState) {
      // Access the state variable here.
    }
    

    I hope this helps!

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