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.
Défi
MoyenL’é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,
);
}
}
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
1Futures
Une valeur qui arrive plus tardAttendre avec async et awaitFonctions qui renvoient des FuturesL’API d’entraînement de Coddy4JSON
Lire du JSONValeurs JSON et asUn constructeur fromJsonUne liste à partir de JSONChamps JSON manquantsEntraînez-vous par vous-même : Compilateur Flutter en ligne