dartflutter

How to load JSON assets into a Flutter App?


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


Solution

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