Menu
CoddyTech

Un botón para volver a intentarlo

Parte de la sección Datos y red del Journey de Flutter de Coddy. Lección 14 de 27.

Las conexiones vuelven. Una buena pantalla de error no deja a la persona atascada: explica qué ocurrió y ofrece una forma de volver a intentarlo.

Volver a intentarlo es recargar: crea un nuevo futuro en setState, igual que un botón de actualizar.

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

Un detalle. Mientras se ejecuta el nuevo futuro, la instantánea conserva el último error, igual que conserva los datos antiguos: hasError sigue siendo true hasta que llega la nueva respuesta. Para mostrar el indicador de carga durante el segundo intento, comprueba primero snapshot.connectionState:

if (snapshot.connectionState == ConnectionState.waiting) {
  return const CircularProgressIndicator();
}
if (snapshot.hasError) {
  // el error y el botón
}
return Text(snapshot.data!);

Para ver cómo falla en la vista previa, escribe offline = true; como primera línea de main y pulsa Ejecutar. offline viene de api.dart: hace que todas las llamadas fallen como si el teléfono no tuviera señal. Quita la línea antes de pulsar Comprobar.

challenge icon

Desafío

Intermedio

Dale al estado de error una forma de recuperarse:

  • debajo del texto de error, añade un botón Try again
  • al pulsarlo, establece un nuevo fetch('/message') en setState
  • el indicador de carga se muestra mientras lo intenta de nuevo: comprueba primero ConnectionState.waiting en el constructor

Pruébalo tú mismo

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 iconPonte a prueba

Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.

Todas las lecciones de Datos y red

Practica por tu cuenta: Compilador de Flutter online