Menu
CoddyTech

Une liste à partir de JSON

Fait partie de la section Données et réseau du Journey Flutter de Coddy. Leçon 18 sur 27.

De nombreuses réponses sont des listes : chaque livre, chaque message, chaque jour d’une prévision. En JSON, une liste s’écrit entre crochets, et ici chaque élément est un objet :

[
  {"title": "Frankenstein", "author": "Mary Shelley"},
  {"title": "Pride and Prejudice", "author": "Jane Austen"}
]

jsonDecode transforme les crochets en une List. Ses éléments sont également de type dynamic, alors indique ce à quoi tu t’attends avec as : List<dynamic> pour la liste, Map<String, dynamic> pour chaque élément.

Transforme ensuite chaque élément en Book avec map, puis rassemble les résultats avec toList() :

final items = jsonDecode(body) as List<dynamic>;
return items
    .map((item) => Book.fromJson(item as Map<String, dynamic>))
    .toList();

map seul renvoie un Iterable paresseux, et non une List, d’où la présence de toList(). L’écran dispose alors d’une List<Book> pour ListView.builder.

challenge icon

Défi

Moyen

L’étagère n’affiche que le premier livre. Fais en sorte que loadBooks transforme chaque élément de la liste en Book, avec items.map(...) et .toList().

Essayez vous-même

import 'dart:convert';

import 'package:flutter/material.dart';

import 'api.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      debugShowCheckedModeBanner: false,
      home: BooksScreen(),
    );
  }
}

class BooksScreen extends StatefulWidget {
  const BooksScreen({super.key});

  @override
  State<BooksScreen> createState() => _BooksScreenState();
}

class _BooksScreenState extends State<BooksScreen> {
  late Future<List<Book>> _books;

  @override
  void initState() {
    super.initState();
    _books = loadBooks();
  }

  Future<List<Book>> loadBooks() async {
    final body = await fetch('/books');
    final items = jsonDecode(body) as List<dynamic>;
    return [Book.fromJson(items[0] as Map<String, dynamic>)];
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Books')),
      body: FutureBuilder<List<Book>>(
        future: _books,
        builder: (context, snapshot) {
          if (snapshot.hasError) {
            return Center(child: Text('Could not load: ${snapshot.error}'));
          }
          if (snapshot.hasData) {
            final books = snapshot.data!;
            return ListView.builder(
              itemCount: books.length,
              itemBuilder: (context, index) {
                final book = books[index];
                return ListTile(
                  title: Text(book.title),
                  subtitle: Text(book.author),
                );
              },
            );
          }
          return const Center(child: CircularProgressIndicator());
        },
      ),
    );
  }
}

class Book {
  Book({required this.title, required this.author});

  final String title;
  final String author;

  factory Book.fromJson(Map<String, dynamic> json) {
    return Book(
      title: json['title'] as String,
      author: json['author'] as String,
    );
  }
}
quiz iconTestez-vous

Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.

Toutes les leçons de Données et réseau

Entraînez-vous par vous-même : Compilateur Flutter en ligne