I've implemented a ListView that loads a Json from internet. So far so good. But I'd like to read a local file in case that attempt to read the online json fails.
I have an async method that reads either a json from internet or from a local asset:
Future<List<Post>> getPosts(String urlJsonInternet, String fileJsonLocal) async {
//read json from internet
await http.get(urlJsonInternet).then((responseInternet) {
//If server returns an OK response, parse the JSON
return _buildPostList(responseInternet.body);
}).catchError((onError) {
//read json from local file
rootBundle.loadString(fileJsonLocal).then((responseLocal) {
return _buildPostList(responseLocal);
});
});
}
_buildPostList it's just a method that parses the json.
To test it I turned off the network at the Android Emulator.
What is happening is that nothing is returned to the Snapshot at FutureBuilder. It seems like something related to the execution order of the process.
This is the screenshot of the exception: https://ibb.co/iMSRsJ
You are making wrong use of asnyc
await
and promises. When using await
, you should not use then
because they do exactly the same. Check this out for reference on Future
's.
You are also returning from the wrong scope, i.e. both of your return
's return to the callbacks and not to your function getPosts. I will rewrite getPosts
with async await
and try catch
.
Lines after await
only get executed once the Future
is finished. More on that here.
Future<List<Post>> getPosts(String urlJsonInternet, String fileJsonLocal) async {
try {
//read json from internet
final responseInternet = await http.get(urlJsonInternet);
//If server returns an OK response, parse the JSON
return _buildPostList(responseInternet.body);
} catch (e) {
//read json from local file
final responseLocal = await rootBundle.loadString(fileJsonLocal);
return _buildPostList(responseLocal);
}
}