Red Screen between screens with Provider

Issue

When I navigate from one page to another a red screen throwing an error is shown very quickly, but afterwards the screen goes normally. It shows The following NoSuchMethodError was thrown building Consumer<StoresManager>. Do you guys know how I can fix this?

here is the onPressed that calls the Navigator:

Container(
        width: _deviceWidht * 0.43,
        height: 27,
        alignment: Alignment.center,
        decoration: BoxDecoration(
            border: Border.all(width: 1, color: Colors.grey),
            borderRadius: BorderRadius.circular(5)),
        child: FlatButton(
            onPressed: () {
              

              Navigator.push(
                  context,
                  MaterialPageRoute(
                    builder: (context) => StoreScreen(
                      profileId: profile.id,
                    ),
                  ));
            },
            child: Text('Comprar')),
      ),

Here is my new screen with a consumer:

class StoreScreen extends StatelessWidget {
 final String profileId;
 final String categoryId;

 final Store store;

 StoreScreen({this.profileId, this.categoryId, this.store});


 @override
  Widget build(
    BuildContext context,
  ) {
    final userManager = context.watch<UserManager>();

   return Consumer<StoresManager>(
     builder: (_, storesManager, __) {
       storesManager.loadStore(profileId);
       if (userManager.adminEnabled) {
        storesManager.store.status = StoreStatus.open;
    }
    return Stack(
      children: [
        gradientBackground(),
        Scaffold(
          appBar: AppBar(
            backgroundColor: Colors.transparent,
            elevation: 0,
            title: Text(
              storesManager.store.name,
              style: TextStyle(fontFamily: 'MontSerrat'),
            ),
            centerTitle: true,
            leading: IconButton(
              icon: Platform.isIOS
                  ? Icon(Icons.arrow_back_ios)
                  : Icon(Icons.arrow_back),
              onPressed: () {
                context.read<CartManager>().clear();
                Navigator.pop(context);
              },
            ),
          ),
          backgroundColor: Colors.transparent,
          body: storesManager.store.status == StoreStatus.closed
              ? AlertDialog(
                  title: Text(storesManager.store.statusText),
                  content: Text(
                      'Horário de funcionamento\n\n${storesManager.store.openningText}'),
                )
              : buildCategories(),
          floatingActionButton: FloatingActionButton(
            backgroundColor: Theme.of(context).primaryColor,
            foregroundColor: Colors.white,
            onPressed: () {
              Navigator.push(
                  context,
                  MaterialPageRoute(
                    builder: (context) => CartScreen(
                      profileId: profileId,
                    ),
                  ));
            },
            child: Icon(Icons.shopping_cart),
          ),
        )
      ],
    );
  },
 );
}
}

my Stack trace:

The following NoSuchMethodError was thrown building Consumer<StoresManager>(dirty,   
dependencies: [_InheritedProviderScope<StoresManager>]):                    
The setter 'status=' was called on null.
Receiver: null
Tried calling: status=Instance of 'StoreStatus'

The relevant error-causing widget was
Consumer<StoresManager>
package:e_ai_casimiro/screens/store_screen.dart:58
When the exception was thrown, this was the stack
#0      Object.noSuchMethod (dart:core-patch/object_patch.dart:51:5)
#1      StoreScreen.build.<anonymous closure>
package:e_ai_casimiro/screens/store_screen.dart:62
#2      Consumer.buildWithChild
package:provider/src/consumer.dart:175

my provider:

class StoresManager extends ChangeNotifier {
   StoresManager() {
 _starTimer();
 }

  Store store;

  String profileId;

  Timer _timer;

  Future<void> loadStore(String profileId) async {
    final snapshot = await storeRef.doc(profileId).get();

    store = Store.fromDocument(snapshot);

    notifyListeners();
   }

  void _starTimer() {
   _timer = Timer.periodic(const Duration(minutes: 1), (timer) {
   _checkOpening();
   });
  }

 void _checkOpening() {
   store.updateStatus();

   notifyListeners();
 }

 @override
 void dispose() {
  super.dispose();
 _timer?.cancel();
 }
}


enum StoreStatus { closed, open, closing }

class Store {
  Store.fromDocument(DocumentSnapshot doc) {
   image = doc['image'] as String;
   name = doc['name'] as String;
   storeId = doc.id;
   delPrice = doc['delPrice'] as num;
   minPrice = doc['minPrice'] as num;
   openning = (doc['openning'] as Map<String, dynamic>).map((key,    
 value) {
   final timeString = value as String;

   if (timeString != null && timeString.isNotEmpty) {
    final splitted = timeString.split(RegExp(r"[:-]"));

    return MapEntry(key, {
      'from': TimeOfDay(
          hour: int.parse(splitted[0]), minute:      
int.parse(splitted[1])),
      'to': TimeOfDay(
          hour: int.parse(splitted[2]), minute: 
int.parse(splitted[3]))
    });
  } else {
    return MapEntry(key, null);
  }
 });
  updateStatus();
 }

String image;
String phone;
String name;
String facebook;
String instagram;
String storeId;
num delPrice;
num minPrice;
Map<String, Map<String, TimeOfDay>> openning;
StoreStatus status;

String get openningText {
 return 'Seg: ${formattedPeriod(openning['monday'])}\n'
    'Ter: ${formattedPeriod(openning['tuesday'])}\n'
    'Qua: ${formattedPeriod(openning['wednesday'])}\n'
    'Qui: ${formattedPeriod(openning['thursday'])}\n'
    'Sex: ${formattedPeriod(openning['friday'])}\n'
    'Sáb: ${formattedPeriod(openning['saturday'])}\n'
    'Dom: ${formattedPeriod(openning['sunday'])}\n';
 }

 String formattedPeriod(Map<String, TimeOfDay> period) {
  if (period == null) return 'Fechado';
  return '${period['from'].formatted()} -   
${period['to'].formatted()}';
}

void updateStatus() {
  final weekDay = DateTime.now().weekday;

  Map<String, TimeOfDay> period;
  if (weekDay == 1) {
    period = openning['monday'];
  } else if (weekDay == 2) {
    period = openning['tuesday'];
  } else if (weekDay == 3) {
    period = openning['wednesday'];
  } else if (weekDay == 4) {
    period = openning['thursday'];
  } else if (weekDay == 5) {
    period = openning['friday'];
  } else if (weekDay == 6) {
    period = openning['saturday'];
  } else if (weekDay == 7) {
    period = openning['sunday'];
 }

final now = TimeOfDay.now();

if (period == null) {
  status = StoreStatus.closed;
} else if (period['from'].toMinutes() < now.toMinutes() &&
    period['to'].toMinutes() - 15 > now.toMinutes()) {
  status = StoreStatus.open;
} else if (period['from'].toMinutes() < now.toMinutes() &&
    period['to'].toMinutes() > now.toMinutes()) {
  status = StoreStatus.closing;
} else {
  status = StoreStatus.closed;
  }
}

String get statusText {
  switch (status) {
    case StoreStatus.closed:
      return 'Loja Fechada';
    case StoreStatus.closing:
      return 'Loja Fecha em 15 minutos';
    default:
    return '';
  }
 }
}

Solution

The line throwing the error is storesManager.store.status = StoreStatus.open;. The error says the store is null. What you can try is adding storesManager.store != null in the condition wrapping that line.

Answered By – MickaelHrndz

Answer Checked By – Mary Flores (FlutterFixes Volunteer)

Leave a Reply

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