Menu
CoddyTech

Lire du JSON

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

Les serveurs répondent rarement par une simple phrase. Ils envoient du JSON : du texte qui contient des données, avec des noms entre guillemets et des valeurs après deux-points. L’API de pratique répond ainsi à /user :

{
  "name": "Maya Chen",
  "email": "maya@example.com",
  "age": 28,
  "isPro": true
}

Pour votre application, c’est une longue String. jsonDecode, de la bibliothèque dart:convert de Dart, transforme ce texte en valeurs Dart. Les accolades deviennent une Map : les noms en sont les clés.

import 'dart:convert';

final Map<String, dynamic> user = jsonDecode(body);
print(user['name']);   // Maya Chen

Les clés sont toujours des chaînes de caractères. Les valeurs peuvent être du texte, des nombres, true ou false, des listes ou d’autres maps ; leur type est donc dynamic : « n’importe quel type, déterminé pendant l’exécution de l’application ». Les clés doivent correspondre exactement : user['Name'] n’est pas user['name'], et une clé manquante renvoie null.

Décodez la réponse au moment où vous la récupérez, dans sa propre fonction, afin que l’écran reçoive des données prêtes à l’emploi.

challenge icon

Défi

Moyen

L’écran de profil affiche le JSON brut. Affiche la personne à la place :

  • loadUser renvoie un Future<Map<String, dynamic>> : il attend fetch('/user') et renvoie le résultat de jsonDecode appliqué au corps (importe dart:convert)
  • _user et FutureBuilder utilisent aussi ce type
  • lorsque les données arrivent, affiche un Column avec user['name'] (taille 28, en gras), puis en dessous user['email']

Essayez vous-même

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: ProfileScreen(),
    );
  }
}

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

  @override
  State<ProfileScreen> createState() => _ProfileScreenState();
}

class _ProfileScreenState extends State<ProfileScreen> {
  late Future<String> _user;

  @override
  void initState() {
    super.initState();
    _user = loadUser();
  }

  Future<String> loadUser() async {
    return fetch('/user');
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Profile')),
      body: Center(
        child: FutureBuilder<String>(
          future: _user,
          builder: (context, snapshot) {
            if (snapshot.hasError) {
              return Text('Could not load: ${snapshot.error}');
            }
            if (snapshot.hasData) {
              return Text(snapshot.data!);
            }
            return const CircularProgressIndicator();
          },
        ),
      ),
    );
  }
}
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