JS/ES6: Destructuring of undefined

JavascriptEcmascript 6

Javascript Problem Overview


I'm using some destructuring like this:

const { item } = content
console.log(item)

But how should I handle content === undefined - which will throw an error?

The 'old' way would look like this:

const item = content && content.item

So, if content is undefined -> item will also be undefined.

Can I do something similar using destructuring?

Javascript Solutions


Solution 1 - Javascript

You can use short circuit evaluation to supply a default if content is a falsy value, usually undefined or null in this case.

const content = undefined
const { item } = content || {}
console.log(item)                       // undefined

A less idiomatic (see this comment) way is to spread the content into an object before destructuring it, because null and undefineds values are ignored.

const content = undefined
const { item } = { ...content }
console.log(item) // undefined

If you are destructuring function params you can supply a default (= {} in the example).

Note: The default value would only be applied if the destructured param is undefined, which means that destructuring null values will throw an error.

const getItem = ({ item } = {}) => item
console.log(getItem({ item: "thing" })) // "thing"
console.log(getItem())                  // undefined

try {
  getItem(null)
} catch(e) {
  console.log(e.message)                // Error - Cannot destructure property `item` of 'undefined' or 'null'.
}

Or even set a default value for the item property if the input object doesn't contain the property

const getItem = ({ item = "default" } = {}) => item
console.log(getItem({ item: "thing" })) // "thing"
console.log(getItem({ foo: "bar" }))    // "default"

Solution 2 - Javascript

const { item } = Object(content)

Solution 3 - Javascript

Destructuring the nested object is clean and short but sucks when source property is null or undefined in right side object

let say we have

const {
  loading,
  data: { getPosts },
} = useQuery(FETCH_POSTS_QUERY);

Solution 1 if we have data object but no getPosts then we can use:
(Setting default at each level)

const {
  loading,
  data: { getPosts = [] } = { getPosts: [] },
} = useQuery(FETCH_POSTS_QUERY);

Solution 2: if event data is undefined then:

const {
  loading,
  data: { getPosts } = { getPosts: [] },
} = useQuery(FETCH_POSTS_QUERY);

Solution 4 - Javascript

One can unpack undefined value, but can't unpack from undefined.
Fixing it is as easy as setting the default params value.

Example:
(() => {
    // prepare payload
	const PAYLOAD = {
		holdingJustThis: 1
	};
    // lets unpack the payload and more
	const {
		holdingJustThis,
		itIsGoingToBeUndefined,
		itCouldThrowButWont: {
			deep
		} = {}                  // this will secure unpacking "deep"
	} = PAYLOAD;

	console.log({
		holdingJustThis
	});
	console.log({
		itIsGoingToBeUndefined  // logs {itIsGoingToBeUndefined:undefined}
	});
	console.log({
		deep                    // logs {deep:undefined}
	});
})()

Solution 5 - Javascript

accepted answer does not work for truely undefined values which were not set by const content = undefined. in such cases this will work:

const { item } = (typeof content !== 'undefined' && content) || {}
console.log(item)

Solution 6 - Javascript

const content = undefined
const { item } = content ?? {}
console.log(item)   // undefined           

Solution 7 - Javascript

I'll just add that for the OP's use case, it is also possible to use the Optional chaining operator:

const item = content?.item
console.log(item)

If content is null or undefined, then content.item will not be accessed and item will be undefined.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionuser3142695View Question on Stackoverflow
Solution 1 - JavascriptOri DroriView Answer on Stackoverflow
Solution 2 - JavascriptВадик ОрловView Answer on Stackoverflow
Solution 3 - JavascriptmabdullahseView Answer on Stackoverflow
Solution 4 - JavascriptMareckyView Answer on Stackoverflow
Solution 5 - JavascriptNir O.View Answer on Stackoverflow
Solution 6 - JavascriptphifaView Answer on Stackoverflow
Solution 7 - JavascriptPapoochView Answer on Stackoverflow