The "Cannot destructure property of undefined" error occurs when we try to destructure a property from a value that is equal to undefined . To solve the error provide a fallback when destructuring the property, e.g. const {name} = undefined || {}; . Here are 2 examples of how the error occurs.
Use the logical OR operator to destructure from a nullable object in TypeScript, e.g. const { name, age } = obj || ({} as Person) . The logical OR operator is used to provide a fallback in case the object has a value of null or undefined . Copied!
Destructuring is a JavaScript expression that allows us to extract data from arrays, objects, and maps and set them into new, distinct variables. Destructuring allows us to extract multiple properties, or items, from an array at a time.
By writing var name = hero.name , you have to mention the name binding 2 times, and the same for realName . That's where the object destructuring syntax is useful: you can read a property and assign its value to a variable without duplicating the property name.
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"
const { item } = Object(content)
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);
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)
One can unpack undefined value, but can't unpack from undefined.
Fixing it is as easy as setting the default params value.
(() => {
// 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}
});
})()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With