Home > Software design >  Flutter - The method '[]' was called on null & Receiver: null & Tried calling: [](0)
Flutter - The method '[]' was called on null & Receiver: null & Tried calling: [](0)

Time:01-29

Below is the code which I am using to to fetch some data from an API

class BreakfastServices {
  final String apiKey = '***************************';
  static const int numberOfFood = 5;
  List<String> foodNameList = [];
  List<String> foodImageList = [];
  List<int> foodDurationList = [];
  /*This class will manage all networking services which includes fetching of the data from the API and decoding
  the JSON file that comes and then returning a list of data*/
  Future<List> getRandomBreakfast() async {
    http.Response response = await http.get(
      Uri.parse(
          'https://api.spoonacular.com/recipes/random?apiKey=$apiKey&number=$numberOfFood&tags=breakfast?'),
    );
    try {
      dynamic foodData = response.body;
      Map data = json.decode(foodData);
      for (int i = 0; i < numberOfFood; i  ) {
        String foodName = (data['recipes'][i]['title']);
        String foodImage = (data['recipes'][i]['image']);
        int foodDuration =
            (data['recipes'][i]['readyInMinutes']); //recipes[1].readyInMinutes
        foodImageList.add(foodImage);
        foodNameList.add(foodName);
        foodDurationList.add(foodDuration);
      }
    } catch (e) {
      //print(e);
    }
    return [foodNameList, foodImageList, foodDurationList];
  }
}

Below is where I am trying to use the data I fetch using a future builder but whenever I do a reload is throws an error of The method '[]' was called on null. for about a second below it works. I know it is because of a null list that will be return before the API returns something but I thought the future builder was supposed to take care of that

FutureBuilder(
                  future: BreakfastServices().getRandomBreakfast(),
                  builder: (context, dynamic snapshot) {
                    List? recipes = snapshot.data[0];
                    List? images = snapshot.data[1];
                    List? foodDuration = snapshot.data[2];
                    if (snapshot.hasData) {
                      return GridView.builder(
                        itemCount: BreakfastServices.numberOfFood,
                        gridDelegate:
                            const SliverGridDelegateWithFixedCrossAxisCount(
                          crossAxisCount: 2,
                          crossAxisSpacing: 10,
                          childAspectRatio: 0.52,
                        ),
                        itemBuilder: (context, index) {
                          return FoodContainer(
                              foodLabel: recipes![index],
                              foodImage: '${images![index]}',
                              time: foodDuration![index],
                              onPressed: () {
                                Navigator.push(
                                  context,
                                  MaterialPageRoute(
                                      builder: (context) => FoodScreen(
                                          foodName: recipes[index],
                                          image: '${images[index]}')),
                                );
                              });
                        },
                      );
                    } else if (snapshot.hasError) {
                      return const Text('Failed to Load');
                    } else {
                      return const Align(child: CircularProgressIndicator());
                    }
                  },
                )

CodePudding user response:

If you initialize the lists before snapshot get the data. the list will be empty. you should add/create list after snapshot get the data.

Move this three line below if(snapshot.hasData) {.

 List<String> recipes = snapshot.data[0] ?? [];
 List<String> images = snapshot.data[1] ?? [];
 List<int> foodDuration = snapshot.data[2] ?? [];
  •  Tags:  
  • Related