I have a list of games displaying on my screen and I want to update that list. When I click the button for the first time, it doesn't work, but when I click it at the second time, the list gets updated.
I tried to add _loadData() after the setState, but also it didn't work.
Here is my class:
class _HomePageState extends State<HomePage> {
bool _isLoading = true;
int _currentPage = 0;
@override
void initState() {
super.initState();
Provider.of<GameController>(
context,
listen: false,
).loadGames(_currentPage).then((value) {
setState(() => _isLoading = false);
});
}
_loadData() async {
await Provider.of<GameController>(
context,
listen: false,
).loadGames(_currentPage);
}
@override
Widget build(BuildContext context) {
final gameController = Provider.of<GameController>(context, listen: false);
final List<Game> loadGames = gameController.games;
final deviceSize = MediaQuery.of(context).size;
return Scaffold(
appBar: AppBar(
title: const Text('Games'),
centerTitle: true,
actions: const [LogoutButton()],
),
body: _isLoading
? const Center(child: CircularProgressIndicator())
: Column(
mainAxisSize: MainAxisSize.max,
children: [
Expanded(
child: SizedBox(
height: deviceSize.height * 0.75,
child: SingleChildScrollView(
child: Column(
children: [
GameList(loadGames),
Container(
margin: const EdgeInsets.only(bottom: 10.0),
child: ElevatedButton(
onPressed: () {
print(_currentPage);
setState(() {
_currentPage++;
_loadData();
});
print(_currentPage);
},
child: const Text('Get more...'),
),
),
],
),
),
),
),
],
),
);
}
}
And here is my function to load the games
Future<void> loadGames(int currentPage) async {
final url = '${Constants.urlGame}?page=$currentPage';
SharedPreferences prefs = await SharedPreferences.getInstance();
final token = prefs.getString('token');
final response = await http.get(
Uri.parse(url),
headers: {'Authorization': '$token'},
);
if (response.statusCode == 200) {
final jsonResponse = jsonDecode(response.body);
final gameList = GameList.fromJson(jsonResponse);
final List<Game> games = gameList.games;
_games.clear();
_games.addAll(games);
notifyListeners();
} else {
print(
response.statusCode,
);
}
}
_loadData()
which is an async operation should not be called inside the setState
method.
According to the documentation itself:
It must not return a future (the callback cannot be async), since then it would be unclear when the state was actually being set.
Instead, you can perform the operation first, and call setState
after.
_currentPage++;
_loadData();
setState(() {});