androidflutterdartasync-awaitandroid-widget

Flutter/Dart: Function return type for returning a ShowDialog based on AsyncValue list


I want to create a function for my app that goes through an Async List to check if an item was previously bought, and show a dialog box if it has been. Since Asyncvalue.when() has data, error and loading parameters, Future Type of showDialog creates return type conflict with CircularProgressIndicator or a Error Text message I could possibly show. Can you let me know if his approach below is faulty, or any suggestions?

Future<Void> itemPreviouslyBought(BuildContext context, Item newItem, AsyncValue<List<Item>> currentItemList) {
    return currentItemList.when(
        data: (item) {
          final matchedElement = item.firstWhere(
                (element) =>
            element.productName.toLowerCase() ==
                newItem.productName.toLowerCase(),
          );
          
          return showDialog<void>(
            context: context,
            barrierDismissible: false,
            builder: (BuildContext context) {
              return AlertDialog(
                title: const Text('Item Previously Bought!'),
                content: SingleChildScrollView(
                  child: ListBody(
                    children: <Widget>[
                      Text("You have bought this item before."),
                    ],
                  ),
                ),
                actions: <Widget>[
                  TextButton(
                    child: const Text('Okay'),
                    onPressed: () {
                      Navigator.of(context).pop();
                    },
                  ),
                ],
              );
            },
          );
        },
      loading: () => const Center(child: CircularProgressIndicator()),
      error: (e, st) => Center(child: Text(e.toString())),
    );
  }

Error message is following Center widget isn't returnable from Future<InvalidType> function.


Solution

  • Future<void> itemPreviouslyBought(BuildContext context, Item newItem, AsyncValue<List<Item>> currentItemList) async {
      return currentItemList.when(
        data: (items) async {
          final matchedElement = items.firstWhere(
            (element) => element.productName.toLowerCase() == newItem.productName.toLowerCase(),
            orElse: () => null,
          );
    
          if (matchedElement != null) {
            await showDialog<void>(
              context: context,
              barrierDismissible: false,
              builder: (BuildContext context) {
                return AlertDialog(
                  title: const Text('Item Previously Bought!'),
                  content: SingleChildScrollView(
                    child: ListBody(
                      children: <Widget>[
                        Text("You have bought this item before."),
                      ],
                    ),
                  ),
                  actions: <Widget>[
                    TextButton(
                      child: const Text('Okay'),
                      onPressed: () {
                        Navigator.of(context).pop();
                      },
                    ),
                  ],
                );
              },
            );
          }
        },
        loading: () async {
          // Handle loading state if needed
        },
        error: (e, st) async {
          // Handle error state if needed
        },
      );
    }
    

    The AsyncValue.when method expects all branches to return the same type, but you’re mixing Future with widgets like Center and Text

    I hope this may resolve your issue,