I have built a Flutter Web application working fine in debug and release mode from my IDE. However, after hosting I see gray screen in one of the widgets.
I know this question has been asked many times, and usually it narrows down to running in debug mode and checking the log if there is any issue like parent widget, expanded, flexible, etc…
I don’t see any error or warning at all.
However, if I run F12 in hosting mode, I see the following error:
Exception: APP_TYPE variable not found. A non-null fallback is required for missing entries
Besides that, there are no issues at all in my debug/release mode built from my IDE.
Here is flutter inspector of the problematic widget (the grayed screen widget)
Copying here problematic widgets code:
Expanded(
flex: 3,
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
AnimatedPackageStatusButton(
index: 0,
selectedIndex: _selectedPackageStatusIndex,
onChange: (idx) =>
selectPackageStatusAction(idx, context),
title: paymentStatusName[
PaymentStatus.values[0]]!
.translate(context),
// packageStatus: getPackageStatusByIndex(0),
),
context.getResponsiveValue(12).hSpace,
AnimatedPackageStatusButton(
index: 1,
selectedIndex: _selectedPackageStatusIndex,
onChange: (idx) =>
selectPackageStatusAction(idx, context),
title: paymentStatusName[
PaymentStatus.values[1]]!
.translate(context),
// packageStatus: getPackageStatusByIndex(1),
),
],
),
context.getResponsiveValue(16).vSpace,
Expanded(
child: Container(
clipBehavior: Clip.antiAlias,
decoration: BoxDecoration(
color: context.colorsTheme.tabBar,
borderRadius: BorderRadius.only(
topLeft: context
.getResponsiveValue(16)
.cRadius,
topRight: context
.getResponsiveValue(16)
.cRadius,
),
),
child: Column(
children: [
PackagesListWidget(
editPackageAction: (Package package) =>
showEditPackageCostModal(package),
packagesList: tabPackagesList,
isItemDisabled: true,
onChecked: (newValue, package) {
int idx =
tabPackagesList.indexOf(package);
setState(
() {
tabPackagesList.removeAt(idx);
tabPackagesList.insert(
idx,
package.copyWith(
isChecked: newValue),
);
},
);
},
),
AnimatedSwitcher(
duration:
const Duration(milliseconds: 300),
child: tabPackagesList.isNotEmpty
? StoreBillingPackagesListFooterActions(
packagesList: tabPackagesList
.where((p) => p.isChecked)
.toList(),
showPrint:
_selectedPackageStatusIndex ==
0,
updateFunc: () => {
setState(() {
updateTabPackages(
context);
})
})
: const SizedBox.shrink(),
),
],
),
),
),
],
),
),
The 2 widgets used in above is. 1 PackagesListWidget
Expanded(
child: widget.packagesList.isEmpty
? EmptyListContainer(
title: 'noPackagesFoundMessage'.translate(context),
)
: ListView.separated(
padding: EdgeInsets.symmetric(
vertical: context.responsiveValue(
mobile: context.getResponsiveValue(20),
largeTablet: 0,
),
),
itemCount: widget.packagesList.length,
itemBuilder: (BuildContext context, int index) {
return PackageListItem(
package: widget.packagesList[index],
selectPackageAction: widget.selectPackageAction,
isSelected:
widget.selectedPackage == widget.packagesList[index],
isDisabled: widget.isItemDisabled,
onChecked: widget.onChecked,
editPackageAction: // todo: this condition should not be inside the package list in this case you can not use the edit in the future for such status
widget.packagesList[index].paymentStatus !=
PaymentStatus.paid
? widget.editPackageAction
: null,
);
},
separatorBuilder: (BuildContext context, int index) {
return context.responsiveValue(
mobile: context.getResponsiveValue(12).vSpace,
largeTablet: Divider(
color: context.colorsTheme.background,
),
);
},
),
);
and the footer:
BlocListener<PackagesBloc, PackagesState>(
listener: (context, state) {
if (state.status == PackagesStatus.loading) {
log('loading packages');
context.read<GlobalLoadingBloc>().add(GlobalStartLoading());
} else if (state.status == PackagesStatus.failed) {
log('loading packages');
context.read<GlobalLoadingBloc>().add(GlobalEndLoading());
showFlashMessage(
flashType: FlashType.error,
bodyText: state.message.translate(context),
);
} else {
context.read<GlobalLoadingBloc>().add(GlobalEndLoading());
updateFunc();
showFlashMessage(
flashType: FlashType.success,
bodyText: "packagesMarkedAsPaidMsg".translate(context),
);
}
},
child: Container(
padding: EdgeInsets.symmetric(
horizontal: context.getResponsiveValue(16),
vertical: context.getResponsiveValue(16),
),
decoration: BoxDecoration(
color: context.colorsTheme.secondary,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(
context.getResponsiveValue(16),
),
topRight: Radius.circular(
context.getResponsiveValue(16),
),
),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Text(
"${'totalSelectedPackages'.translate(context)}: ",
style: context.textTheme.normalMedium.copyWith(
color: context.colorsTheme.onSecondary,
),
),
context.getResponsiveValue(8).hSpace,
Text(
packagesList.length.toString(),
style: context.textTheme.boldMedium.copyWith(
color: context.colorsTheme.onSecondary,
),
),
],
),
Row(
children: [
Text(
"${'totalToPay'.translate(context)}: ",
style: context.textTheme.normalMedium.copyWith(
color: context.colorsTheme.onSecondary,
),
),
Text(
(packagesList.fold(
0.0,
(previousValue, element) =>
previousValue + element.cost)).toStringAsFixed(2),
style: context.textTheme.boldMedium.copyWith(
color: context.colorsTheme.onSecondary,
),
),
],
),
],
),
!showPrint || packagesList.isEmpty
? const SizedBox.shrink()
: Link(
text: 'markSelectedAsPaid'.translate(context),
onTap: () {
showMarkPackageAsPaidModal(context);
},
textColor: context.colorsTheme.onSecondary,
),
!showPrint || packagesList.isEmpty
? const SizedBox.shrink()
: Link(
text: 'printSelected'.translate(context),
onTap: () {
context.push(
RoutePaths.packagePDFScreenRoute.path,
extra: {
"packagesList": packagesList,
"summary": true,
"pdfFor": "store",
},
);
},
textColor: context.colorsTheme.onSecondary,
),
],
),
),
);
2
Answers
Its the usage of .env!
apparently web app does not support any .env files, files must be .env, I have renamed the file to dotenv_prod.env (and changes relevant usages) and everything worked!
I took the answer from this stack-overflow thread relying on Kelvin Jou answer and comment
Getting "Another exception was thrown: Instance of 'minified:bV<void>'" while running flutter app on web (localhost)
Looking at your widget tree, I can see that one of the
Expanded
widgets is sitting inside aPadding
widget.PackageListItem -> Row -> Padding -> Expanded
This must be causing an
Invalid Parent data widget exception
that creates the "grey screen" issue. Please refer to the attached image pointing out the exact level in the tree where the problem lies.Try keeping the
Expanded
directly under theRow
and then wrap it underPadding
Reference: https://docs.flutter.dev/testing/common-errors#incorrect-use-of-parentdata-widget%5Benter image description here]1