How to load JSON assets into Flutter App
Try out :
String data = await DefaultAssetBundle.of(context).loadString("assets/data.json");
final jsonResult = json.decode(data);
@Alexandre Beaudet's answer is correct but doesn't give a lot of context about what is going on.
When you're calling loadString
, it's actually an asynchronous method call. You can tell because it returns a Future<value>
rather than just a value
. This means that it doesn't immediately have a result of String, but will at some point in the future.
There are two main ways of dealing with asynchronicity in Dart; the first being to use async
and await
, the second being to use the futures directly. See the dart guide on Asynchronous Programming.
If you use future.then
directly, you can do it from a normal function (i.e. from initState etc). You simply specify the callback and in the callback what to do with the result.
void printDailyNewsDigest() {
final future = gatherNewsReports();
future.then((news) => print(news));
}
If you want to use await
as @Alexandre has illustrated, you need to mark the function you are using it from as async
, i.e.:
Future<Void> printDailyNewsDigest() async {
String news = await gatherNewsReports();
print(news);
}
If you override a function (i.e. initState) you also need to make sure you don't change the return value. That should get caught by dart 2's typing most of the time, but void -> Future doesn't seem to be.
One last thing to note - if you're using the result of the data to build widgets, you'll probably want to look at using a FutureBuilder.
I use the following to parse json in assets:
import 'dart:convert';
import 'package:flutter/services.dart' show rootBundle;
//...
Future<Map<String, dynamic>> parseJsonFromAssets(String assetsPath) async {
print('--- Parse json from: $assetsPath');
return rootBundle.loadString(assetsPath)
.then((jsonStr) => jsonDecode(jsonStr));
}
Usage async:
parseJsonFromAssets(path)
.then((dmap) => {
// here you get json `dmap` as Map<String, dynamic>
print(dmap);
}));
Usage sync:
Map<String, dynamic> dmap = await parseJsonFromAssets('assets/test.json');