paint-brush
Acceso a objetos anidados en JavaScriptpor@flexdinesh
238,550 lecturas
238,550 lecturas

Acceso a objetos anidados en JavaScript

por Dinesh Pandiyan2018/02/20
Read on Terminal Reader
Read this story w/o Javascript
tldt arrow
ES

Demasiado Largo; Para Leer

<strong>tldr;</strong> <em>acceda de forma segura a objetos anidados en JavaScript de una manera genial.</em>

Company Mentioned

Mention Thumbnail
featured image - Acceso a objetos anidados en JavaScript
Dinesh Pandiyan HackerNoon profile picture

tldr; acceda de forma segura a objetos anidados en JavaScript de una manera genial.

JavaScript es increíble, todos lo sabemos ya. Pero algunas cosas en JavaScript son realmente extrañas y nos hacen rascarnos mucho la cabeza. Una de esas cosas es la confrontación con este error cuando intenta acceder a un objeto anidado,

No se puede leer la propiedad 'foo' de undefined

La mayoría de las veces, cuando trabajamos con JavaScript, trataremos con objetos anidados y, a menudo, necesitaremos acceder a los valores anidados más internos de forma segura.

Tomemos este objeto anidado como ejemplo.

 const user = { id: 101, email: '[email protected]', personalInfo: { name: 'Jack', address: { line1: 'westwish st', line2: 'washmasher', city: 'wallas', state: 'WX' } }}

Para acceder al nombre de nuestro usuario, escribiremos

 const name = user.personalInfo.name;const userCity = user.personalInfo.address.city;

Esto es fácil y directo.

Pero, por alguna razón, si la información personal de nuestro usuario no está disponible, la estructura del objeto será así:

 const user = { id: 101, email: '[email protected]'}

Ahora, si intenta acceder al nombre, se le arrojará No se puede leer la propiedad 'nombre' de undefined .

 const name = user.personalInfo.name; // Cannot read property 'name' of undefined

Esto se debe a que estamos tratando de acceder a la clave de name desde un objeto que no existe.

La forma habitual en que la mayoría de los desarrolladores lidian con este escenario es,

 const name = user && user.personalInfo ? user.personalInfo.name : null;// undefined error will NOT be thrown as we check for existence before access

Esto está bien si su estructura anidada es simple, pero si tiene sus datos anidados en 5 o 6 niveles de profundidad, entonces su código se verá realmente desordenado como este,

 let city;if ( data && data.user && data.user.personalInfo && data.user.personalInfo.addressDetails && data.user.personalInfo.addressDetails.primaryAddress ) { city = data.user.personalInfo.addressDetails.primaryAddress;}

Hay algunos trucos para lidiar con estas estructuras de objetos desordenadas.

Patrón de acceso a objetos anidados de Oliver Steele

Este es mi favorito personal ya que hace que el código se vea limpio y simple . Escogí este estilo de stackoverflow hace un tiempo y es bastante pegadizo una vez que entiendes cómo funciona.

 const name = ((user || {}).personalInfo || {}).name;

Con esta notación, nunca se encontrará con Cannot read property 'name' of undefined . Básicamente, verifica si el usuario existe, si no, crea un objeto vacío sobre la marcha. De esta forma, siempre se accederá a la clave del siguiente nivel desde un objeto existente o un objeto vacío , pero nunca desde indefinido.

Desafortunadamente, no puede acceder a matrices anidadas con este truco

Acceder a objetos anidados usando Array Reduce

El método de reducción de matriz es muy poderoso y se puede usar para acceder de manera segura a objetos anidados.

 const getNestedObject = (nestedObj, pathArr) => { return pathArr.reduce((obj, key) => (obj && obj[key] !== 'undefined') ? obj[key] : undefined, nestedObj);} // pass in your object structure as array elementsconst name = getNestedObject(user, ['personalInfo', 'name']); // to access nested array, just pass in array index as an element the path array.const city = getNestedObject(user, ['personalInfo', 'addresses', 0, 'city']);// this will return the city from the first address item.

mecanografiado

Si cree que los métodos anteriores son demasiado convencionales, entonces debería probar la biblioteca Typy que he escrito. Además de acceder de forma segura a los objetos anidados, hace muchas más cosas asombrosas. 🎉

Está disponible como un paquete npm — Typy

Si usa Typy , su código se verá así,

 import t from 'typy'; const name = t(user, 'personalInfo.name').safeObject;const city = t(user, 'personalInfo.addresses[0].city').safeObject;// address is an array

Hay algunas otras bibliotecas como Lodash y Ramda que pueden hacer esto. Pero en proyectos front-end livianos, especialmente si solo necesitará uno o dos métodos de esas bibliotecas, es una buena idea optar por una biblioteca alternativa liviana, o mejor, escribir la suya propia.

¡Feliz 'acceso seguro a objetos anidados en JavaScript'! 💥