0

I have this function:

  Future<List<String>> _readJson(String path) async {
    Directory appDocDir = await getApplicationDocumentsDirectory();
    String appDocPath = appDocDir.path + '/' + path;
    String response = await File(appDocPath).readAsString();

    final data = await (json.decode(response) as List<dynamic>).cast<String>();

    return data;
  }

As you can see, the output is a Future<List<String>>. I want to assign the output of this function to a new list like this (to be able to iterate through the elements:

  void _function(Map<dynamic, dynamic> playbackData) {
    ...

    List<String> jsonList = readJSON('landmarks.json') as List<String>;

    for(int i = 0; i <= jsonList.length - 1; ++i){
      print(jsonList[i]);
    }
  }

But this is my error:

[ERROR:flutter/lib/ui/ui_dart_state.cc(198)] Unhandled Exception: type 'Future<List<String>>' is not a subtype of type 'List<String>' in type cast

I know that the output is a Future List of Strings but I am deliberately casting it to a List of strings for that purpose. Where am I going wrong?

Onur-Andros Ozbek
  • 2,998
  • 2
  • 29
  • 78
  • Not sure why you have that second `await`. Have you tried to replace your `final data` line with: `final data = (json.decode(response) as List).cast();` ? – julemand101 Jun 15 '22 at 12:11
  • Have you tried to label your `_function` as `async` and then `await` for `readJSON` response? Maybe that'll do. – KHAN Jun 15 '22 at 12:13
  • Also, this is never going to work `List jsonList = readJSON('landmarks.json') as List;` since you need to await the returned future. You are working with async code. A `Future` means something that is going to potentially have a value later at some point. You can therefore not just cast this directly to a value. The point of `await` is to halt the current running code and let other events on the event queue running so the future might get a value. When the future gets a value, your code is ready to be executed. – julemand101 Jun 15 '22 at 12:13
  • Does this answer your question? [What is a Future and how do I use it?](https://stackoverflow.com/questions/63017280/what-is-a-future-and-how-do-i-use-it) – nvoigt Jun 15 '22 at 12:17
  • "Not sure why you have that second await. Have you tried to replace your final data line with: final data = (json.decode(response) as List).cast(); " Tried it. No difference. – Onur-Andros Ozbek Jun 15 '22 at 12:23

2 Answers2

1

Just await the return and you will get List<String>

and change the return type to

_readJson(String path) async {
    Directory appDocDir = await getApplicationDocumentsDirectory();
    String appDocPath = appDocDir.path + '/' + path;
    String response = await File(appDocPath).readAsString();

    final data = json.decode(response);

    return data;
  }

Then to read its data

List<dynamic> jsonList = await readJSON('landmarks.json');
for(int i = 0; i <= jsonList.length - 1; ++i){
      print(jsonList[i]);
    }
Kaushik Chandru
  • 15,510
  • 2
  • 12
  • 30
0

I've managed to read a Future<List<String>> with the following code. Just await for your result before assigning it to jsonList. Don't forget to mark your function as async too:

void _function(Map<dynamic, dynamic> playbackData) async {
  ...

  List<String> jsonList = await readJSON('landmarks.json');

  for (int i = 0; i <= jsonList.length - 1; ++i) {
    print(jsonList[i]);
  }
}
KHAN
  • 537
  • 5
  • 12