CharacterPage? currentPage;
...
Future<dynamic> pageGetter(int i, CharacterPage? x) async {
Dio dio = Dio();
var pageData =
await dio.get('https://rickandmortyapi.com/api/character?page=$i'); // => here i am
if (pageData.statusCode == HttpStatus.ok) { //updating the
x = CharacterPage.fromJson(pageData.data); //page number
} //with int i
if (mounted) {
setState(() {});
}
}
...
List<Character> filterByName() {
pageGetter(1, currentPage);
for (var v = 0; v < currentPage!.info.pages; v++) {
pageGetter(v+1, currentPage);
for (var i = 0; i < currentPage!.results.length; i++) {
if (currentPage!.results.elementAt(i).name.contains("$nameFilterText")) {
filteredByName.add(currentPage!.results.elementAt(i));
}
}
}
...
TextButton(
onPressed: () {
filteredByName = [];
results = filterByName();
setState(() {});
},
child: Text("Search"))
Here, what i am trying to do here is; on pressed, the Text button should run the pageGetter function which sends a get request. For example first it gets the page number 1, and makes a filtering on a parameter which is name, than adds objects to an empty list. Then i want it to get page number 2 with help of the for loop and make the same filtering on it untill there are no more pages left - there are 42 pages on this data here - which i am trying to do it on updating currentPage variable which is an instance of a class that i created. But everytime the inner for loop runs, it makes the filtering on the page number 1. i think the currentPage becomes updated when the all for loops concluded, which leads the same filtering on page 1 for 42 times. If i press that button again, i get random objects filtered from random pages.
I want this function to first make it's filtering on page 1, add the elements to the list than update the currentPage to page 2 than make the filtering on page 2 and add the elements and go on untill all the pages are filtered but i couldn't figure out why currentPage isn't updated during the process but at the end of it.
I hope I was clear about my problem, thanks in advance.
When you call pageGetter
in a loop, it doesn't wait for the previous call to complete before making the next call.
you can use async/await
to wait for each call to pageGetter
to complete before making the next call.
List<Character> filterByName() async {
currentPage = await pageGetter(1, currentPage);
for (var v = 1; v <= currentPage!.info.pages; v++) {
currentPage = await pageGetter(v, currentPage);
for (var i = 0; i < currentPage!.results.length; i++) {
if (currentPage!.results.elementAt(i).name.contains("$nameFilterText")) {
filteredByName.add(currentPage!.results.elementAt(i));
}
}
}
return filteredByName;
}
Also, you'll need to modify your TextButton's
onPressed
callback to handle the asynchronous nature of the filterByName function:
TextButton(
onPressed: () async {
filteredByName = [];
results = await filterByName();
setState(() {});
},
child: Text("Search"),
)