I'm currently doing a purchase feature on my App. Whenever free users click on a premium feature, it'll pop to the previous screen and users can now using the premium feature.
This is the current code I have:
Check on premium feature:
if (!PremiumUtils.checkLifetimePremium(user?.premiumStatus) &&
!PremiumUtils.checkSubscriptionPremium(user?.premiumExpireDate)) {
Navigator.push(context, _createUpgradeRoute());
}
If the user is a free user, display the Upgrade UI. And I used the PremiumUtils
to check whether the purchase is done or not, to navigate between routes:
part of pages;
class Upgrade extends StatelessWidget {
const Upgrade({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
UserModel? user = context.watch<AppViewModel>().userModel;
return ChangeNotifierProvider(
create: (context) => UpgradeViewModel(),
child: Builder(
builder: (context) {
return Consumer<UpgradeViewModel>(
builder: (context, provider, child) {
if (PremiumUtils.checkLifetimePremium(user?.premiumStatus) ||
PremiumUtils.checkSubscriptionPremium(user?.premiumExpireDate)) {
Navigator.pop(context);
}
return the UI;
}
}
));
}
}
This obviously causing the setState() or markNeedsBuild() called during build
exception. And I can't think of any way around.
Please give me some idea about this problem!
Wrap it in Future.microtask
. This will schedule it to happen on the next async task cycle (i.e. after build
is complete).
Future.microtask(() => Navigator.push(
context,
MaterialPageRoute(builder: (context) => LoginView())
))