skip to Main Content

I am currently working on an application that involves searching for foods from an API. I have a search bar that is sending queries, and I am getting foods back from my API calls. However, these items are not populating. Here I have some code to you a better idea of my problem:

void _showSearchModal(BuildContext context) {
    showModalBottomSheet(
        context: context,
        isScrollControlled: true,
        builder: (BuildContext context) {
          return FractionallySizedBox(
              heightFactor: 0.8,
              child: Container(
                  color: Color(0xff2a2a2a),
                  child: CustomScrollView(
                    slivers: [
                      SliverAppBar(
                        // ... //
                      ),
                      SliverList(
                        delegate: SliverChildBuilderDelegate( //Here is the builder for my list
                          (context, index) {
                            return FoodTile(
                                foodItem: searchResults[index]);
                          },
                          childCount: searchResults.length,
                        ),
                      )
                    ],
                  )));
        });
  }

And here is the function that is sending the queries and updating the list containing the results of the search

List<FoodItem> searchResults = []; 

void _searchFood(String query) async {
    if (query.isEmpty) {
      setState(() {
        searchResults.clear();
      });
      return;
    }

    List<Map<String, dynamic>> fetchedResults = await fetchFood(query);

    List<FoodItem> foodItems = [];
    for (var foodMap in fetchedResults) {
      try {
        FoodItem foodItem = FoodItem.fromJson(foodMap);
        foodItems.add(foodItem);
      } catch (e) {
        print("Error creating FoodItem from JSON: $e");
      }
    }
    setState(() {
      searchResults = foodItems;
    });
  }

I have tried:

  1. Making searchResults a list of food tiles and creating those food tiles outside of the SliverChildBuilderDelegate
  2. Printing out the length and contents of searchResults after setting the state and verifying its contents
  3. Creating a local variable inside of the SliverChildBuilderDelegate and setting that equal to the searchResults

2

Answers


  1. this maybe because of context. that showModalBottomSheet widget is not rebuilding on SetState call.
    try this

    // create a key for your widget
    GlobalKey<State<StatefulWidget>> bottomSheetKey = GlobalKey();
    
    
    // assign the key to top level widget in you builder here
    void _showSearchModal(BuildContext context) {
    showModalBottomSheet(
        context: context,
        isScrollControlled: true,
        builder: (BuildContext context) {
          return FractionallySizedBox(
              // in this case here
              key: bottomSheetKey,
              heightFactor: 0.8,
              ...
              );
        });
     }
    
    void _searchFood(String query) async {
       ...
        // use this bottomSheetKey to trigger rebuild on FractionallySizedBox so it will rebuild the ui in ModalBottomSheet
        bottomSheetKey.currentState?.setState(() {
          searchResults = foodItems;
        });
       ....
    
      }
    
    Login or Signup to reply.
  2. try using ListView.builder it may help

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