web-dev-qa-db-fra.com

Comment charger des ressources JSON dans l'application Flutter

Comment charger un actif JSON dans mon application Flutter?

Mon fichier pubspec.yaml contient les éléments suivants:

  assets:
    - assets/data.json

Je n'arrête pas d'essayer de charger les données. j'ai essayé 

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

Mais j'ai l'erreur

Le type d'argument 'Future <String>' ne peut pas être affecté au type de paramètre 'String'.

Merci!

9
nalyd88

La réponse de @Alexandre Beaudet est correcte mais ne donne pas beaucoup de contexte sur ce qui se passe.

Lorsque vous appelez loadString, il s’agit en fait d’un appel de méthode asynchrone. Vous pouvez le savoir car cela retourne un Future<value> plutôt que simplement une value. Cela signifie qu’il n’a pas immédiatement pour résultat String, mais le sera ultérieurement.

Il y a deux manières principales de traiter l'asynchronicité dans Dart; le premier étant d'utiliser async et await, le second étant d'utiliser directement les futures. Voir le guide des fléchettes Programmation asynchrone .

Si vous utilisez directement future.then, vous pouvez le faire à partir d’une fonction normale (par exemple, à partir de initState, etc.). Vous spécifiez simplement le rappel et, dans le rappel, que faire avec le résultat.

void printDailyNewsDigest() {
  final future = gatherNewsReports();
  future.then((news) => print(news));
}

Si vous voulez utiliser await comme l'a illustré @Alexandre, vous devez marquer la fonction à partir de laquelle vous l'utilisez comme async, c'est-à-dire:

Future<Void> printDailyNewsDigest() async {
  String news = await gatherNewsReports();
  print(news);
}

Si vous substituez une fonction (par exemple, initState), vous devez également vous assurer de ne pas modifier la valeur de retour. Cela devrait être attrapé par Dart 2 en tapant la plupart du temps, mais vide -> Future ne semble pas l'être.

Une dernière chose à noter - si vous utilisez le résultat des données pour créer des widgets, vous voudrez probablement utiliser un FutureBuilder .

7
rmtmckenzie

Essaie :

String data = await DefaultAssetBundle.of(context).loadString("assets/data.json");
final jsonResult = json.decode(data);
13
Alexandre Beaudet

J'utilise les éléments suivants pour analyser JSON dans les actifs:

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

Utilisation async:

parseJsonFromAssets(path)
    .then((dmap) => {
    // here you get json `dmap` as Map<String, dynamic>
    print(dmap);
}));

Sync d'utilisation:

Map<String, dynamic> dmap = await parseJsonFromAssets('assets/test.json');
2
thundertrick