Menu
CoddyTech

El estado de error de FutureBuilder

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

FutureBuilder captura los errores por ti. Cuando su futuro lanza una excepción, nada falla: el constructor se ejecuta de nuevo con snapshot.hasError establecido en true, y snapshot.error contiene lo que se lanzó.

Eso da a cada pantalla de carga tres estados, y el constructor se ocupa de cada uno:

if (snapshot.hasError) {
  return Text('Could not load: ${snapshot.error}');
}
if (snapshot.hasData) {
  return Text(snapshot.data!);
}
return const CircularProgressIndicator();

Error, datos y, de lo contrario, todavía se está cargando. Un constructor que solo sabe manejar datos muestra el indicador de carga para siempre cuando la llamada falla, porque nunca hay datos.

Coloca cada comprobación antes del return que la ocultaría. Si el return del indicador de carga aparece primero para «sin datos», la línea del error que está debajo nunca podrá ejecutarse.

Para ver cómo falla en la vista previa, escribe offline = true; como primera línea de main y pulsa Run. offline proviene 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 Check.

challenge icon

Desafío

Intermedio

Sin conexión, esta pantalla carga indefinidamente. Proporciona al constructor su estado de error: cuando snapshot.hasError, muestra Could not load: seguido de snapshot.error, con tamaño 20.

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.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