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