19

Destructing is cool but I start to encounter serious issues when doing destructing of nested objects. I have this code:

const {
      credit: { amont },
    } = userProfile

This is dangerous because what if credit is null? the whole app breaks. How do I prevent this? I know one way is to use Typescript but I'd rather not. I start to doubt destructing for nested has no difference from using dot.

ggorlen
  • 44,755
  • 7
  • 76
  • 106
Hoknimo
  • 533
  • 2
  • 6
  • 15

4 Answers4

46

It isn't possible to solve this with deep destructuring. As another answer suggests, it's possible to use default values but they are applied only to undefined values:

const { credit: { amont } = {} } = userProfile || {};

While null values still result in error, it's necessary to do short-circuit evaluation for all objects that can potentially be nully:

const { credit } = userProfile || {};
const { amont } = credit || {};

This can be addressed with safe navigation utility function that reads the path and checks for nully values.

A renowned example is Lodash get:

const amont = _.get(userProfile, 'credit.amont');

I know one way is to use typescript but here I don't

It's possible to address this with TypeScript only if type safety is guaranteed. If userProfile comes from JSON response, runtime type checks have to be applied to assert that objects aren't null.

Estus Flask
  • 206,104
  • 70
  • 425
  • 565
  • 1
    so avoid `null` at all cost? – Hoknimo Aug 30 '18 at 02:38
  • @Hoknimo Yes, it's less practical than undefined for destructuring. But since you may get it from some sources (e.g. there's no undefined in JSON), you have to deal with null any way. – Estus Flask Aug 30 '18 at 10:30
  • then avoid nested destructuring? because looking at the api response I couldn't tell whether there will be undefined object property at all. – Hoknimo Aug 30 '18 at 12:53
  • Yes, destructuring isn't useful here. You need to process response first, e.g. replace null with undefined and possibly other changes if your data structure differs from API response. – Estus Flask Aug 30 '18 at 19:17
3

You can avoid your app crashes by giving default values while destructing:

const {
  credit: { amont } = {},
} = userProfile
console.log(amont); //amont will be undefined

You can later check amont by !!amont where ever you're using it.

Sakhi Mansoor
  • 7,832
  • 5
  • 22
  • 37
1

In Javascript, a variable can be assigned a default, in the case that the value unpacked from the object / array is undefined. To avoid deep de-structuring read-only property of an object(which is null), you can assign default values like this. In this case an empty object.

enter image description here

1

This worked for me when, data[0].attributes.artist.data === null

  const {
    id: artworkArtistId,
    attributes: { name: artworkArtistName, slug: artworkArtistSlug } = {},
  } = data[0].attributes.artist.data || {};

  console.log("artworkArtistId", artworkArtistId);
  console.log("artworkArtistName", artworkArtistName);
  console.log("artworkArtistSlug", artworkArtistSlug);

enter image description here

if data array is empty

  const {
    images: { data: images } = { data: [] },
  } = props.props || {};
atazmin
  • 4,757
  • 1
  • 32
  • 23