How to load JSON assets into a Flutter App?

DartFlutter

Dart Problem Overview


How do I load a JSON asset into my Flutter app?

My pubspec.yaml file has the following:

assets:
    - assets/data.json

I keep getting stuck trying to load the data. I tried:

final json = JSON.decode(
    DefaultAssetBundle.of(context).loadString("assets/data.json")
);

But I get the error:

> The argument type 'Future< String>' can't be assigned to the parameter type 'String'.

Dart Solutions


Solution 1 - Dart

Try out :

String data = await DefaultAssetBundle.of(context).loadString("assets/data.json");
final jsonResult = jsonDecode(data); //latest Dart

Solution 2 - Dart

@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.

Solution 3 - Dart

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');

Solution 4 - Dart

You can use this code :)

loadJson() async {
  String data = await rootBundle.loadString('assets/json/keyboard.json');
  jsonResult = json.decode(data);
  print(jsonResult);
}

Can load on start :)

  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance.addPostFrameCallback((_) async {
      await loadJson();
    });
  }

Need to add the JSON on the asset

flutter:
  uses-material-design: true
  assets:
    - assets/json/keyboard.json

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionnalyd88View Question on Stackoverflow
Solution 1 - DartAlexandre BeaudetView Answer on Stackoverflow
Solution 2 - DartrmtmckenzieView Answer on Stackoverflow
Solution 3 - DartthundertrickView Answer on Stackoverflow
Solution 4 - DartRafsan Uddin Beg RizanView Answer on Stackoverflow