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] ?? [];
