简体   繁体   中英

BlocProvider.of() called with a context that does not contain a Bloc of type OfflineBloc

I'm trying to understand multiBloc with offline database from already created project. I have created demo project same as already created project. but getting exception and unable to understand why it is happening.

actually I'm fetching data from api with bloc pattern and trying to save these data in local database for offline use.

and data is being fetched & you can see my email id in console.But after fetching data i'm trying to hit GetOfflineQueueData() event but getting below bloc exception.

Note: I'm using multi BLOc.

class _MainHomePageState extends State<MainHomePage> {
  var resultDate ;
  LandingBloc _landingBloc;
  OfflineBloc _offlineBloc;
 // Completer<void> _refreshCompleter;

  @override
  void initState() { 
    resultDate = DateTime.now();
    _landingBloc = BlocProvider.of<LandingBloc>(context);
    // _offlineBloc = BlocProvider.of<OfflineBloc>(context);
    super.initState();
    if(AppConfig().isUserLoggedInFirstTime){
      _landingBloc.setDate(DateTime.now());
    }


  }

  @override
  Widget build(BuildContext context) {

    // print("userProfileEmail_______________________________________________________${widget.userProfile?.emailAddress}");
    return Scaffold(
     backgroundColor: Colors.white,
      appBar: AppBar(
        elevation: 1.0,
        backgroundColor: Colors.white,
        title: Padding(
          padding: const EdgeInsets.all(8.0),
          child: Image.asset('assets/images/logo.png', width: 200, height: 50),
        ),
        iconTheme: new IconThemeData(color: Colors.black),
        actions: <Widget>[
        IconButton(
            icon: Icon(Icons.search),
            onPressed: () {
              Navigator.of(context).push(MaterialPageRoute(builder: (context)=> SearchPage()));
            },
          ) 
        ],
        centerTitle: true,
      ),
      body: BlocBuilder(
        bloc: _landingBloc,
        builder: (BuildContext context, LandingState state) {

          if(state is UserProfileFetched){
            return buildBodyWidget();
          }
          return showSpinner();  
        }),


       drawer: buildDrawer(),

    );
  }



Widget buildDrawer(){ 
    Widget getDrawer;
    if (   AppConfig().isOnline!= null && AppConfig().userProfile != null ) {
      getDrawer = BlocBuilder(
        bloc: _landingBloc,
        builder: (BuildContext context, LandingState state){
          if(state is UserProfileFetched){
            print("object UserProfileFetched _if:$state ");
            print("state.userProfileeeeeeeeeeeeee Email:${state.userProfile.emailAddress}");
            BlocProvider<OfflineBloc>.value(
              value: BlocProvider.of<OfflineBloc>(context),
              child: DrawerWidget(state.userProfile),
            );  
          }
          print("object state else :$state ");
          return BlocProvider<OfflineBloc>.value(
            value: BlocProvider.of<OfflineBloc>(context)..dispatch(GetOfflineQueueData()),
            child: DrawerWidget(AppConfig().userProfile),
          ); 
        }
      );
      // getDrawer = DrawerWidget(AppConfig().userProfile);
    }
    else if (AppConfig().isOnline != null && AppConfig().userProfile != null) {
       getDrawer = BlocProvider<OfflineBloc>.value(
        value: BlocProvider.of<OfflineBloc>(context)..dispatch(GetOfflineQueueData()),
        child: DrawerWidget(AppConfig().userProfile),
      );
    } 
    else{
     getDrawer = null;
    }
    return getDrawer;  
  }

}


Offline bloc

lass OfflineBloc extends Bloc<OfflineEvent, OfflineState> {
  OfflineApi _offlineApi = OfflineApi();
  // OrdersApi _ordersApi = OrdersApi();

  int queueCount = 0;
  List<SyncQueueDBModel> queueData;

  @override
  OfflineState get initialState => InitialOfflineState();

  @override
  Stream<OfflineState> mapEventToState(OfflineEvent event,) async* {

   if (event is GetOfflineQueueData) {
      List<SyncQueueDBModel> queue = await _offlineApi.getQueue();
      queueData = queue;
      print("Sync Queue from offline bloc");
      print(queue);
      queueCount = queue.length;

      yield OfflineQueueDataFetched(count: queue.length);
    }

  }
}



Offline events:

import 'package:meta/meta.dart';

@immutable
abstract class OfflineEvent {}

class SyncAllMasterTable extends OfflineEvent {}

class CheckMasterTableUpdate extends OfflineEvent {}

class UpdateMasterTable extends OfflineEvent {}

class SyncOfflineQueue extends OfflineEvent {}

class ResyncAllMasterTable extends OfflineEvent {}

class DeleteAllOfflineData extends OfflineEvent {}

class DeleteOfflineMasterData extends OfflineEvent {}

class GetOfflineQueueData extends OfflineEvent {}

Offline states:

import 'package:meta/meta.dart';

@immutable
abstract class OfflineState {}

class InitialOfflineState extends OfflineState {}

class RequestSyncForSpeficMasterTableSyncing extends OfflineState {}

class OfflineOperationInProgress extends OfflineState {}

class SyncAllMasterDataCompleted extends OfflineState {}

class DeleteAllOfflineDataCompleted extends OfflineState {}

class DeleteOfflineMasterDataCompleted extends OfflineState {}

class OfflineQueueDataFetched extends OfflineState {
  final int count;
  OfflineQueueDataFetched({@required this.count});
}

class OfflineQueueSynched extends OfflineState {}

Console OutPut with exception:

estarted application in 2,674ms.
I/flutter (19578): Instance of 'InitNetworkConnectivity'
I/flutter (19578): Instance of 'FetchAppSettings'
I/flutter (19578): Instance of 'SetNetworkStatus'
I/flutter (19578): Transition { currentState: Instance of 'InitialNetworkConnectivityState', event: Instance of 'SetNetworkStatus', nextState: Instance of 'NetworkOnline' }
I/flutter (19578): Connected => WiFi
I/flutter (19578): Transition { currentState: Instance of 'InitialAppSettingsState', event: Instance of 'FetchAppSettings', nextState: Instance of 'AppSettingsFetched' }
I/flutter (19578): Instance of 'ValidateToken'
I/flutter (19578): /data/user/0/com.example.etteo_demo/app_flutter/authentication_token.json
I/flutter (19578): Transition { currentState: Instance of 'InitialSessionState', event: Instance of 'ValidateToken', nextState: Instance of 'SessionTokenValid' }
I/flutter (19578): Instance of 'FetchUserProfile'
I/flutter (19578): Transition { currentState: Instance of 'InitialLandingState', event: Instance of 'FetchUserProfile', nextState: Instance of 'UserProfileFetchingState' }
I/flutter (19578): USERRRR_PROFILE_RESULT{userId: 764bf12f-cf16-4ffd-927d-b93165d14fea, resourceId: e56f7c8b-7b01-4aa1-83e2-230dc024d250, firstName: shruti, lastName: sharma, emailAddress: shrutiramnandansharma@gmail.com, phoneNumber: null, countryCode: null, smsFl: false, contactId: 38cd2eaf-04fa-4176-9c33-b50f7640c37d, timeZoneId: 0b96c1c4-12bc-4dc9-86f4-38cb817a847d, timeZoneName: Eastern Standard Time, timeZoneTime: (UTC-05:00) Eastern Time (US & Canada), profileImage: null, createdDate: 2020-02-13T07:21:46.1404603+00:00, address: {addressId: 0, addressTypeId: 4, addressLine1: null, addressLine2: null, addressLine3: null, addressLine4: null, addressLine5: null, city: null, state: null, postalCode: null, country: null, latitude: null, longitude: null}, website: {websiteId: 0, websiteUrl: null, websiteDescription: null}, roles: [Admin], permissions: [UserManagement, ResourceManagement, ManageProviderProfile, UpdateOrderDocument, OverrideCapacity, UpdateDelegateDocument, UpdateOrderNoteVisibility, ManageDelegateRelationship,
I/flutter (19578): Transition { currentState: Instance of 'UserProfileFetchingState', event: Instance of 'FetchUserProfile', nextState: Instance of 'UserProfileFetched' }
I/flutter (19578): object UserProfileFetched _if:Instance of 'UserProfileFetched'
I/flutter (19578): state.userProfileeeeeeeeeeeeee Email:shrutiramnandansharma@gmail.com


════════ Exception caught by widgets library ═══════════════════════════════════
The following assertion was thrown building BlocBuilder<LandingBloc, LandingState>(dirty, state: _BlocBuilderBaseState<LandingBloc, LandingState>#ca0e2):
        BlocProvider.of() called with a context that does not contain a Bloc of type OfflineBloc.

        No ancestor could be found starting from the context that was passed to BlocProvider.of<OfflineBloc>().

        This can happen if:
        1. The context you used comes from a widget above the BlocProvider.
        2. You used MultiBlocProvider and didn't explicity provide the BlocProvider types.

        Good: BlocProvider<OfflineBloc>(builder: (context) => OfflineBloc())
        Bad: BlocProvider(builder: (context) => OfflineBloc()).

        The context used was: BlocBuilder<LandingBloc, LandingState>(dirty, state: _BlocBuilderBaseState<LandingBloc, LandingState>#ca0e2)

The relevant error-causing widget was
    BlocBuilder<LandingBloc, LandingState> 
package:etteo_demo/…/mainHome/main_home_page.dart:101
When the exception was thrown, this was the stack
#0      BlocProvider.of 
package:flutter_bloc/src/bloc_provider.dart:66
#1      _MainHomePageState.buildDrawer.<anonymous closure> 
package:etteo_demo/…/mainHome/main_home_page.dart:108
#2      BlocBuilder.build 
package:flutter_bloc/src/bloc_builder.dart:83
#3      _BlocBuilderBaseState.build 
package:flutter_bloc/src/bloc_builder.dart:150
#4      StatefulElement.build 
package:flutter/…/widgets/framework.dart:4334
...
════════════════════════════════════════════════════════════════════════════════


Error Screenshot , When I Click on drawer:

在此处输入图片说明

Step 1:

You should not call BlocProvider.of(context) inside initState method. Instead move your call to didChangeDependencies method.

This method is also called immediately after initState. It is safe to call BuildContext.dependOnInheritedWidgetOfExactType from this method.

Example:

@override
void didChangeDependencies() {

//fetch your bloc here.
//...


super.didChangeDependencies();
}

Step 2:

You should ensure your desired Bloc is available for the given context. If not, you should add BlocProvider to your current scaffold tree.

The culprit here is that you are using BlocProvider.of(context)inside buildDrawer() method which has no reference to the OfflineBloc. simply pass the OfflineBloc inside this method or just wrap the Scaffold with BlocProvider. Check your initState that you have commented this:

// _offlineBloc = BlocProvider.of<OfflineBloc>(context);

or if your want to create your Bloc in this page then use create to create new instance of the OfflineBloc.

 BlocProvider<OfflineBloc>(
          create: (context) => _offlineBloc,
   child:Scaffold(
    body:...........
    BlocBuilder(
    bloc: _landingBloc,
     builder: (BuildContext context, LandingState state) {

      if(state is UserProfileFetched){
        return buildBodyWidget();
      }
      return showSpinner();  
    }),


   drawer: buildDrawer(),

);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM