Menu
CoddyTech

Un pulsante per riprovare

Fa parte della sezione Dati e rete del percorso Flutter di Coddy. Lezione 14 di 27.

Le connessioni tornano. Una buona schermata di errore non lascia la persona bloccata: spiega cosa è successo e offre un modo per riprovare.

Riprovare equivale a ricaricare: crea una nuova future in setState, proprio come un pulsante di aggiornamento.

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

Un dettaglio. Mentre viene eseguita la nuova future, lo snapshot mantiene l'ultimo errore, proprio come mantiene i dati precedenti: hasError resta true finché non arriva la nuova risposta. Per mostrare lo spinner durante il secondo tentativo, controlla prima snapshot.connectionState:

if (snapshot.connectionState == ConnectionState.waiting) {
  return const CircularProgressIndicator();
}
if (snapshot.hasError) {
  // l'errore e il pulsante
}
return Text(snapshot.data!);

Per vedere l'errore nell'anteprima, scrivi offline = true; come prima riga di main e premi Run. offline proviene da api.dart: fa sì che ogni chiamata fallisca come se il telefono non avesse segnale. Rimuovi la riga prima di premere Check.

challenge icon

Sfida

Medio

Offri una via d'uscita dallo stato di errore:

  • sotto il testo dell'errore, aggiungi un pulsante Riprova
  • premendolo, imposta una nuova fetch('/message') in setState
  • lo spinner viene mostrato mentre riprova: controlla prima ConnectionState.waiting nel builder

Provalo tu

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 iconMettiti alla prova

Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.

Tutte le lezioni di Dati e rete

Esercitati da solo: Compilatore Flutter online