Datos que llegan incompletos
El backend te promete un campo y no llega. Cómo proteger la UI sin tapar el bug real.
- optional chaining
- nullish coalescing
- manejo de errores
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
- Encadena
?.en cada punto donde el objeto podría no existir. ??no es||: piensa qué pasa con0,""yfalse.- Un
.catch()no es opcional cuando la red puede fallar.
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().
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.
Comprueba lo que has aprendido
1. ¿Qué pasa cuando `user.profile` es `undefined` y ejecutas `user.profile.name`?
2. ¿Cuál es la diferencia real entre `??` y `||` en JavaScript?
3. Cargas un producto con `precio: 0`. ¿Qué imprime `producto.precio || 'sin precio'`?
4. ¿Por qué añadir `.catch()` en la cadena de `fetch`?
5. El campo `name` era obligatorio por contrato con backend. ¿Qué se hace además de proteger la UI con `??`?