BlocProvider.of () вызывается с контекстом, который не содержит Blo c типа OfflineBloc - PullRequest
0 голосов
/ 05 марта 2020

Я пытаюсь понять multiBlo c с автономной базой данных из уже созданного проекта. Я создал демонстрационный проект так же, как уже созданный проект. но получаю исключение и не могу понять, почему это происходит.

на самом деле я получаю данные из API с шаблоном blo c и пытаюсь сохранить эти данные в локальной базе данных для автономного использования.

и данные извлекаются, и вы можете увидеть мой электронный идентификатор в консоли. Но после извлечения данных я пытаюсь вызвать событие GetOfflineQueueData(), но получаю исключение blo c.

Примечание: я использование мульти BLO c.

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;  
  }

}


Автономный блок c

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);
    }

  }
}



Автономные события:

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 {}

Автономные состояния:

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 {}

Выход консоли с исключением:

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
...
════════════════════════════════════════════════════════════════════════════════


Снимок экрана ошибки, когда я нажимаю на ящик:

enter image description here

Ответы [ 2 ]

0 голосов
/ 05 марта 2020

Причиной здесь является то, что вы используете BlocProvider.of (context) внутри метода buildDrawer (), который не имеет ссылки на OfflineBlo c. просто передайте OfflineBlo c внутри этого метода или просто оберните Scaffold с BlocProvider. Проверьте свой initState, что вы прокомментировали это:

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

или если вы хотите создать свой Blo c на этой странице, то используйте create для создания нового экземпляра OfflineBlo c.

 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(),

);
0 голосов
/ 05 марта 2020

Шаг 1:

Вы не должны вызывать BlocProvider.of(context) внутри initState метода. Вместо этого переместите ваш вызов в метод didChangeDependencies .

Этот метод также вызывается сразу после initState. Можно безопасно вызывать BuildContext.dependOnInheritedWidgetOfExactType из этого метода.

Пример:

@override
void didChangeDependencies() {

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


super.didChangeDependencies();
}

Шаг 2:

Вы должны убедиться, что Ваш желаемый Blo c доступен для данного контекста. Если нет, вы должны добавить BlocProvider в ваше текущее дерево скаффолдов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...