Search code examples
flutterif-statementdartreturn

Flutter ignores return statement inside of "if" branch


I am trying to create a filter from a list of objects using the PopupMenuButton Widget. I think the logic is sound but Flutter/Dart appears to ignore the return statement inside of the 'if branch' in my function called "fliterFavs" in the code chunk below.

When I select "Favs" it is recognized as expected and the print statement before the return works fine.

When I use that very same return statement in the place of the one outside the 'if statement', it works fine. I get back the filtered data set that I expect.

I have even tried it as two back to back if statements, instead of the nested one you see below. It still does not work.

any ideas?

final List<Product> favProducts = [];

  Widget filterFavs(value) {
    loadedProducts.forEach((i) {
      if (i.isFavorite == true) {
        favProducts.add(i);
        if (value == "Favs") {
          print(value);
          return buildGrid(favProducts);
        }
      }
    });
    return buildGrid(loadedProducts);
  }

  Widget buildGrid(List newList) {
    return GridView.builder(
      padding: const EdgeInsets.all(10.0),
      itemCount: newList.length,
      itemBuilder: (ctx, i) => ProductItem(
        newList[i].id,
        newList[i].title,
        newList[i].imageUrl,
      ),
      gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
        crossAxisCount: 2,
        childAspectRatio: 3 / 2,
        crossAxisSpacing: 10,
        mainAxisSpacing: 10,
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text('MyShop'),
          actions: <Widget>[
            PopupMenuButton(
              onSelected: (val) {
                filterFavs(val);
              },
              icon: Icon(
                Icons.more_vert,
              ),
              itemBuilder: (context) => [
                PopupMenuItem(
                  child: Text("Favs"),
                  value: "Favs",
                ),
                PopupMenuItem(
                  child: Text("All"),
                  value: "All",
                ),
              ],
            ),
          ],
        ),
        //use a filter on the item builder
        body: filterFavs(context));
  }
}


Solution

  • Think about the function that the return you're referring to returns from. It's returning to the anonymous function passed to the forEach method, not to filterFavs like you expect. It's not an issue with flutter/dart, it's an issue with your expectation.

    You can use the alternative for-each syntax to solve this:

    Widget filterFavs(value) {
      for(var i in loadedProducts) {
        if (i.isFavorite == true) {
          favProducts.add(i);
          if (value == "Favs") {
            print(value);
            return buildGrid(favProducts);
          }
        }
      }
      return buildGrid(loadedProducts);
    }