How to access data in Bloc's state from another bloc

Issue

I am developing a Flutter application using Bloc pattern. After success authentication, UserSate has User object. In all other Blocs, I need to access User object in UserState. I tried with getting UserBloc on other Bloc’s constructor parameters and accessing User object. But it shows that User object is null. Anyone have a better solution?

class SectorHomeBloc extends Bloc<SectorHomeEvent, SectorHomeState> {
  final OutletRepository outletRepository;
  UserBloc userBloc;
  final ProductRepository productRepository;
  final ProductSubCategoryRepository productSubCategoryRepository;
  final PromotionRepository promotionRepository;
  final ProductMainCategoryRepository mainCategoryRepository;

  SectorHomeBloc({
    @required this.outletRepository,
    @required this.userBloc,
    @required this.productSubCategoryRepository,
    @required this.productRepository,
    @required this.promotionRepository,
    @required this.mainCategoryRepository,
  });
  @override
  SectorHomeState get initialState => SectorHomeLoadingState();

  @override
  Stream<SectorHomeState> mapEventToState(SectorHomeEvent event) async* {
    try {
      print(userBloc.state.toString());
      LatLng _location = LatLng(
          userBloc.state.user.defaultLocation.coordinate.latitude,
          userBloc.state.user.defaultLocation.coordinate.longitude);
      String _token = userBloc.state.user.token;

      if (event is GetAllDataEvent) {
        yield SectorHomeLoadingState();
        List<Outlet> _previousOrderedOutlets =
            await outletRepository.getPreviousOrderedOutlets(
                _token, _location, event.orderType, event.sectorId);

        List<Outlet> _featuredOutlets =
            await outletRepository.getFeaturedOutlets(
                _token, _location, event.orderType, event.sectorId);
        List<Outlet> _nearestOutlets = await outletRepository.getOutletsNearYou(
            _token, _location, event.orderType, event.sectorId);

        List<Product> _newProducts = await productRepository.getNewItems(
            _token, _location, event.orderType, event.sectorId);

        List<Product> _trendingProducts =
            await productRepository.getTrendingItems(
                _token, _location, event.orderType, event.sectorId);

        List<Promotion> _promotions = await promotionRepository
            .getVendorPromotions(_token, event.sectorId);
        yield SectorHomeState(
          previousOrderedOutlets: _previousOrderedOutlets,
          featuredOutlets: _featuredOutlets,
          nearByOutlets: _nearestOutlets,
          newItems: _newProducts,
          trendingItems: _trendingProducts,
          promotions: _promotions,
        );
      }
    } on SocketException {
      yield SectorHomeLoadingErrorState('could not connect to server');
    } catch (e) {
      print(e);
      yield SectorHomeLoadingErrorState('Error');
    }
  }
}

The print statement [print(userBloc.state.toString());] in mapEventToState method shows the initial state of UserSate.
But, at the time of this code executing UserState is in UserLoggedInState.

Solution

there is an official way to do this as in the documentation, called Bloc-to-Bloc Communication
and here is the example for this as in the documentation

class MyBloc extends Bloc {
  final OtherBloc otherBloc;
  StreamSubscription otherBlocSubscription;

  MyBloc(this.otherBloc) {
    otherBlocSubscription = otherBloc.listen((state) {
        // React to state changes here.
        // Add events here to trigger changes in MyBloc.
    });
  }

  @override
  Future<void> close() {
    otherBlocSubscription.cancel();
    return super.close();
  }
}

Answered By – Baraa Aljabban

Answer Checked By – Katrina (FlutterFixes Volunteer)

Leave a Reply

Your email address will not be published. Required fields are marked *