Flutter: get default context? or load assets without context?


Flutter: get default context? or load assets without context?



I'm trying to load a json file in a class extending SearchDelegate to search through its content.



I have a method to load this file:


Future<void> loadCountryData() async {
try {
String data = await DefaultAssetBundle
.of(context)
.loadString("assets/data/countries.json");
_countries = json.decode(data);
} catch (e) {
print(e);
}
}



Unfortunately this requires a Buildcontext (context) that seems only to be available in the SearchDelegate build methods (like buildActions, buildLeadings, etc), but no outside like for example in the constructor.



https://docs.flutter.io/flutter/material/SearchDelegate-class.html



As the @override xy build methods in SearchDelegate are called with every change in the search field, I would load my file over and over again, which is of course not ideal.
I want to load my file once at the beginning only.



Is there a way to get some sort of get default context that I could use for example in the constructor of SearchDelegate. Like in android (if I remmeber correctly)?



Or can I load an assets file without .of(context)?


.of(context)




2 Answers
2



You can give the BuildContext as a parameter through to loadCountryData(BuildContext context).


BuildContext


loadCountryData(BuildContext context)



As DefaultAssetBundle is based on an InheritedWidget you will always need to pass a context.


DefaultAssetBundle


InheritedWidget



of just looks up the widget tree based on a BuildContext until it finds a DefaultAssetBundle widget. This means that you cannot retrieve a DefaultAssetBundle object without a BuildContext.


of


BuildContext


DefaultAssetBundle


DefaultAssetBundle


BuildContext



You will need to pass a BuildContext to your method. I could imagine a situation like the following:


BuildContext


@override
Widget build(BuildContext context) {
return FutureBuilder(
future: loadCountryData(context: context),
builder: (BuildContext context, AsyncSnapshot<JSON> jsonData) {
if (!jsonData.hasData) {
return Text('not loaded');
}
return Text('loaded'); // here you want to process your data
},
);
}

/// I am not sure what your decode returns, so I just called it JSON
/// I thought it would make more sense to return the JSON to use it in build
Future<JSON> loadCountryData({BuildContext context}) async {
try {
String data = await DefaultAssetBundle
.of(context)
.loadString("assets/data/countries.json");
return json.decode(data);
} catch(e) {
print(e);
return JSON.empty(); // imagine this exists
}
}



As you can see I passed the BuildContext from the build method. The FutureBuilder also allows to process the data in the build tree directly.


BuildContext


build


FutureBuilder






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Popular posts from this blog

Render GeoTiff to on browser with leaflet

How to get chrome logged in user's email id through website

using states in a react-navigation without redux