1
votes

Créer une liste à partir de JSON dans Flutter

Suite à un exemple en ligne, j'ai le code suivant:

body: Column(
    children: <Widget>[
      Padding(
        padding: EdgeInsets.all(10.0),
        child: TextField(
          onChanged: (value) {
            ...
          },
          controller: _searchController,
          decoration: InputDecoration(

          ...
          ),
        ),
      ),
      Expanded(
        child: SizedBox(
          height: 200.0,
          child: ListView.builder(
              itemCount: list.length,
              itemBuilder: (BuildContext context, int index) {
                return Text(list[index].title);
              }),
        ),
      )
    ],
  ),

Ce qui renvoie cette erreur:

class Model {
  final String title;
  final String docid;

  Model._({this.title, this.docid});

  factory Model.fromJson(Map<String, dynamic> json) {
    return new Model._(
      title: json['title'],
      docid: json['docid'],
    );
  }
}

Voici la réponse de l'API:

{"results":[{"docid":"123434","title":"A title"}, ...]}

Modèle:

Unhandled Exception: type '_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'List<dynamic>' in type cast

Je comprends que l'usine ci-dessus s'attend à ce que l'argument soit Map<String, dynamic> et que le format du json est différent et peut être modifié, mais je veux savoir comment le faire fonctionner avec ce format.

*** Éditer

Liste de travail

_fetchData() async {
    setState(() {
      isLoading = true;
    });

    final response = await http.get(
        "https://apiurl...");

    if (response.statusCode == 200) {
      print(json.decode(response.body).runtimeType); // _InternalLinkedHashMap<String, dynamic>

      list = (json.decode(response.body) as List)
          .map((data) => Model.fromJson(data))
          .toList();

      setState(() {
        isLoading = false;
      });
    } else {
      throw Exception('Failed to load');
    }
  }


2 commentaires

essayez d'utiliser jsonDecode place json.decode .


Sur cette ligne json.decode(response.body) as List , essayez plutôt avec json.decode(response.body) as List<String, dynamic> et faites-nous savoir.


4 Réponses :


9
votes

La raison pour laquelle print(json.decode(response.body).runtimeType) imprime _InternalLinkedHashMap est que le niveau supérieur de votre json est en effet une carte; {"results":[ s'ouvre avec une accolade.

Ainsi, json.decode(response.body) n'est pas une liste et ne peut pas être converti en une seule. D'autre part, json.decode(response.body)['results'] est une liste.

Vous avez besoin:

  list = json.decode(response.body)['results']
      .map((data) => Model.fromJson(data))
      .toList();


7 commentaires

Hé, merci pour ta réponse. print(list) renvoie [Instance of 'Model', Instance of 'Model', ...] Est-ce correct? Je n'arrive pas à faire fonctionner le ListView. Cela a également été ajouté à la question.


Cela devrait être list[index].title . Votre liste est maintenant correctement imprimée que vous avez plusieurs modèles. Indexez les index dans la liste, vous donnant un modèle, et vous accédez à la variable membre par son nom avec un point.


Je suis sûr que j'ai essayé avec dot, mais je vais regarder à nouveau. Merci


J'ai modifié ma question en indiquant comment je souhaite utiliser le widget ListView. Flutter renvoie ce message: flutter: Another exception was thrown: RenderBox was not laid out: RenderViewport#67a95 NEEDS-LAYOUT NEEDS-PAINT


J'ai trouvé la réponse ici: stackoverflow.com/questions/52801201/… . Semble que le widget ListView doit être enveloppé par un SizedBox


génial! Essayez également Expanded comme alternative à la boîte de taille.


J'ai créé une classe modèle mais rien n'est appelé lors de la tentative de création de la liste. Existe-t-il un moyen de faire cela sans créer de classe?



3
votes

j'ai essayé comme ça et ça a marché

[{"id":4,"name":"1","email":"admin","password":"dc4b79a9200aa4630fee652bb5d7f232c503b77fb3b66df99b21ec3ff105f623","user_type":"1","created_on":"2020-01-13 12:50:28","updated_on":"2020-01-14 11:42:05","flags":"00000"},{"id":31,"name":"avi","email":"asdf@gmail.com","password":"dc4b79a9200aa4630fee652bb5d7f232c503b77fb3b66df99b21ec3ff105f623","user_type":"1","created_on":"2020-03-15 11:39:16","updated_on":"2020-03-15 11:39:16","flags":null}]

Ma réponse Json est comme: -

List<UserModel> users = (json.decode(response.body) as List)
      .map((data) => UserModel.fromJson(data))
      .toList();


1 commentaires

J'ai créé une classe modèle mais rien n'est appelé lors de la tentative de création de la liste. Existe-t-il un moyen de faire cela sans créer de classe?



1
votes

Ce qui suit fonctionnait pour moi:

List<Model>.from(
  json.decode(response.body)
  .map((data) => Model.fromJson(data))
)


0 commentaires

-3
votes

les éléments suivants résolvent ce code et fonctionnent correctement:

réponse finale = attendre http.get ("https://about.google/static/data/locations.json");

données finales = jsonDecode (response.body) ['offices'];


0 commentaires