I am building a screen in an app using an existing model class which I can't modify. The model has a method called refreshList()
which fetches some data from an API, processes it, and finally it updates a List
member in a model with the fetched data.
I want to know the state of the list - i.e. is it uninitialized, being fetched or already fetched - so that I can update the UI accordingly.
The problem is that refreshList()
is not async
, but uses an async
method internally. Additionally, the internal method doesn't return a Future
.
void refreshList(){
if( someCondition ){
_doRefreshList();
}
}
void _doRefreshList() async{
// ... do stuff
http.Response response = await http.get(url);
// ... do some more stuff
}
I would like to do something like
setState((){ _isLoading = true; });
await model.refreshList();
setState((){ _isLoading = false; });
but unfortunately I can't modify the methods in the model to return a Future
.
Is there any way to achieve this without modifying refreshList()
to be async
and return a Future
, and modifying _doRefreshList()
to return a Future
?
No, there is no way to wait for an asynchronous operation to complete unless it provides some way to get a callback when it's done. The usual way to do that is to return a future. Having a callback function parameter is another approach, but it's rarely better than just returning a future.
In your example, refreshVerList
has no way to report when it is done, and neither does _doRefreshList
. You will have to add that somehow, and returning a future is the simplest and most consistent way to solve the problem for both functions.
(Technically, the _doRefreshList
function does return a future, it's just typed as void
. You can cast that future to Future
, but I strongly discourage that kinds of shenanigans. If the function author decides to return something else, say null
, at a later point, they are perfectly within their right to do since the return type is void
.)