Portal Performance
datos

Datos que llegan incompletos

El backend te promete un campo y no llega. Cómo proteger la UI sin tapar el bug real.

El problema

Renderizas datos que vienen del backend. En pruebas todo funciona: el endpoint devuelve el JSON esperado con su profile.name dentro. En producción, un día cualquiera, llega una respuesta con profile: null (o sin profile), y la app entera casca con un TypeError que ni siquiera sabes dónde tratar.

El error es doble: la interfaz no está preparada para datos irregulares, y no hay manejo de fallo alguno en la promesa. Ambas cosas se arreglan sin taparle al backend que te está mandando basura.

El código “roto”

function mostrarUsuario(user) {
  const el = document.getElementById("username");
  el.textContent = user.profile.name;
}

fetch("/api/user")
  .then((res) => res.json())
  .then((user) => mostrarUsuario(user));

Las pistas

Ver la solución
function mostrarUsuario(user) {
  const el = document.getElementById("username");
  el.textContent = user?.profile?.name ?? "Anónimo";
}

fetch("/api/user")
  .then((res) => res.json())
  .then((user) => mostrarUsuario(user))
  .catch((err) => console.error("No se pudo cargar el usuario:", err));

El optional chaining (?.) corta la evaluación si algo por el camino es null o undefined, y devuelve undefined en vez de lanzar. El nullish coalescing (??) sustituye ese undefined por el fallback, pero solo cuando el valor es null o undefined — deja pasar 0, "" y false, que sí pueden ser datos válidos.

El .catch está para el caso realista: la red se cae, el servidor tarda demasiado o devuelve un JSON que no se puede parsear. Sin él, el error se convierte en un unhandled promise rejection silencioso que solo verás si abres la consola.

Falta una cosa que este snippet no cubre: si name era obligatorio en el contrato de datos, el bug es del backend. El ?? "Anónimo" evita que la UI se caiga, pero no arregla nada. Repórtalo. Los fallbacks tapan síntomas, no problemas.

Como bonus, fetch no rechaza en respuestas 4xx o 5xx — solo en fallos de red. Si quieres tratarlos como error, comprueba res.ok antes de llamar a res.json().

Pruébalo

Datos que llegan sin profile

Un fetch simulado devuelve un objeto sin profile. La versión rota accede a user.profile.name y se rompe con unTypeError — que en tu app real sería unUncaught (in promise) silencioso en la consola. La versión con?., ?? y .catch devuelve "Anónimo" y sigue funcionando.

esperando
Nombre de usuario

Comprueba lo que has aprendido

  1. 1. ¿Qué pasa cuando `user.profile` es `undefined` y ejecutas `user.profile.name`?

  2. 2. ¿Cuál es la diferencia real entre `??` y `||` en JavaScript?

  3. 3. Cargas un producto con `precio: 0`. ¿Qué imprime `producto.precio || 'sin precio'`?

  4. 4. ¿Por qué añadir `.catch()` en la cadena de `fetch`?

  5. 5. El campo `name` era obligatorio por contrato con backend. ¿Qué se hace además de proteger la UI con `??`?