Menu
CoddyTech

Un bouton pour réessayer

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

Les connexions reviennent. Un bon écran d’erreur ne laisse pas la personne bloquée : il indique ce qui s’est passé et propose un moyen de réessayer.

Réessayer revient à recharger : crée un nouveau future dans setState, comme avec un bouton d’actualisation.

void tryAgain() {
  setState(() {
    _message = fetch('/message');
  });
}

Un détail. Pendant l’exécution du nouveau future, le snapshot conserve la dernière erreur, comme il conserve les anciennes données : hasError reste à true jusqu’à l’arrivée de la nouvelle réponse. Pour afficher l’indicateur de chargement pendant la deuxième tentative, vérifie d’abord snapshot.connectionState :

if (snapshot.connectionState == ConnectionState.waiting) {
  return const CircularProgressIndicator();
}
if (snapshot.hasError) {
  // l'erreur et le bouton
}
return Text(snapshot.data!);

Pour voir l’échec dans l’aperçu, écris offline = true; comme première ligne de main et appuie sur Run. offline vient de api.dart : cela fait échouer chaque appel comme si le téléphone n’avait pas de réseau. Supprime cette ligne avant d’appuyer sur Check.

challenge icon

Défi

Moyen

Prévoyez une issue à l’état d’erreur :

  • sous le texte d’erreur, ajoutez un bouton Try again
  • l’appui sur ce bouton définit un nouveau fetch('/message') dans setState
  • le spinner s’affiche pendant la nouvelle tentative : vérifiez d’abord ConnectionState.waiting dans le constructeur

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

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

  @override
  State<MessageScreen> createState() => _MessageScreenState();
}

class _MessageScreenState extends State<MessageScreen> {
  late Future<String> _message;

  @override
  void initState() {
    super.initState();
    _message = fetch('/message');
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: FutureBuilder<String>(
          future: _message,
          builder: (context, snapshot) {
            if (snapshot.hasError) {
              return Text(
                'Could not load: ${snapshot.error}',
                style: const TextStyle(fontSize: 20),
              );
            }
            if (snapshot.hasData) {
              return Text(snapshot.data!, style: const TextStyle(fontSize: 24));
            }
            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