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.