Contenido del curso

Estados de carga y errores en Flutter

Resumen

Cuando consumes una API en Flutter, no siempre recibes una respuesta limpia y exitosa. A veces los datos tardan, llegan vacíos o la petición falla. Aprender a manejar estados de carga y errores en Flutter te permite construir interfaces más robustas y mejorar la experiencia de quien usa tu aplicación.

Aquí vas a ver cómo cubrir los tres escenarios más comunes con FutureBuilder, validaciones condicionales y un bloque try catch para tu llamada HTTP.

¿Cómo mostrar un indicador de carga mientras llega la data?

Antes de construir la vista final, necesitas validar el estado de la conexión del snapshot. Si la petición sigue en proceso, lo correcto es mostrar un loader centrado.

El widget que usas aquí es CircularProgressIndicator, que despliega un círculo girando hasta que la información termine de cargar. Lo envuelves en un Center para que quede en medio de la pantalla.

dart if (snapshot.connectionState == ConnectionState.waiting) { return const Center( child: CircularProgressIndicator(), ); }

¿Qué hace ConnectionState.waiting en Flutter? Indica que el Future aún no ha terminado de resolverse. Mientras esté en ese estado, tu app debe mostrar un indicador visual de carga.

¿Cómo validar si la respuesta de la API llega vacía?

Después del estado de carga, agregas un else if para cubrir dos posibles casos: que el dato venga null o que llegue como lista vacía. Ambos significan que no hay nada que mostrar al usuario, aunque la petición haya sido exitosa.

La validación combina dos preguntas: si el snapshot tiene data y si esa data está vacía con isEmpty. Si alguno se cumple, retornas un texto centrado con un mensaje claro.

dart else if (!snapshot.hasData || snapshot.data!.isEmpty) { return const Center( child: Text('No recipes found'), ); }

Para probarlo rápido, puedes enviar una lista vacía desde tu mock y verificar que aparezca el mensaje al recargar la aplicación.

¿Y cuándo muestro la información correcta?

Cuando ninguno de los dos casos anteriores se cumple, significa que tienes datos válidos. Ese es el momento de retornar tu ListView con las recetas renderizadas dentro del else final.

  • if para el estado de carga.
  • else if para data nula o vacía.
  • else para mostrar la lista real.

Con esos tres bloques cubres todos los escenarios que ve tu usuario en pantalla.

¿Cómo capturar errores de la llamada HTTP con try catch?

Validar el front no es suficiente. También necesitas blindar la función que hace la petición a la API. Para eso envuelves la lógica en un bloque try catch que atrape cualquier excepción durante la llamada.

Dentro del try, esperas la respuesta de la URL y revisas el statusCode. Si es 200, procesas y guardas la data para enviarla al front. Si no, imprimes un error en consola con el código recibido y devuelves una lista vacía.

dart try { final response = await http.get(url); if (response.statusCode == 200) { // procesar y retornar data } else { print('Error response: ${response.statusCode}'); return []; } } catch (e) { print('Error en la request'); return []; }

Fíjate en el detalle de la interpolación: para insertar una variable dentro de un string en Dart usas signo pesos seguido de llaves, así: ${response.statusCode}. Esto te permite acceder a propiedades de la variable directamente.

¿Por qué retornar una lista vacía en lugar de null? Porque ya tienes una validación en el front que muestra "No recipes found" cuando la lista está vacía. Mantener el mismo tipo de retorno evita errores y reutiliza tu lógica de UI.

¿Qué diferencia hay entre el error del front y el de la llamada?

Son dos capas distintas que conviene separar:

  • El error de front ocurre cuando la data llega vacía o nula y necesitas comunicarlo visualmente.
  • El error de request ocurre cuando la API falla, el statusCode no es 200 o se lanza una excepción.
  • El estado de loading ocurre mientras la petición está en curso, sin importar su resultado final.

Manejar las tres capas te da control total sobre lo que ve el usuario en cada momento.

¿Por qué importa cubrir todos los estados en una app móvil?

Una app que no maneja carga ni errores deja al usuario frente a una pantalla en blanco o, peor, frente a un crash. Con CircularProgressIndicator, validaciones de snapshot y un try catch bien colocado, conviertes esos momentos incómodos en señales claras: "estamos cargando", "no hay datos" o "algo falló".

Eso es lo que diferencia un prototipo de un producto listo para clientes reales. ¿Cómo estás manejando hoy los errores en tus pantallas con Flutter? Cuéntalo en los comentarios.