skip to Main Content

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

enter image description here

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)
enter image description here

enter image description here

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


  1. Chosen as BEST ANSWER

    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)


  2. Looking at your widget tree, I can see that one of the Expanded widgets is sitting inside a Padding 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 the Row and then wrap it under Padding

    Reference: https://docs.flutter.dev/testing/common-errors#incorrect-use-of-parentdata-widget%5Benter image description here]1

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search