Reputation: 976
I have the following object in my state and I'm trying to access the bracket and entries properties.
This is how I try to access the attributes, however I just get "cannot access attribut of undefined" errors
function App () {
const [ladder, setLadder] = useState({})
useEffect(() => {
async function fetchMyAPI () {
try {
const res = await axios.get(
'data/wow/pvp-season/27/pvp-leaderboard/3v3?namespace=dynamic-eu&locale=en_US&access_token=12345'
)
setLadder(res)
} catch (error) {
console.log(error)
}
}
fetchMyAPI()
}, [])
return (
<>
{console.log(ladder.data.bracket)} // cannot access bracket of undefined ...
{console.log(ladder.data.entries[0])} // cannot access entries of undefined ...
</>
)
}
Upvotes: 0
Views: 39
Reputation: 3043
You're getting that error because on the first render (which occur on load up of the component), the state variable ladder
is an empy object. Only after the data is fetched, the variable is updated. So You can "render nothing" as long as ladder.data
is undefined
by checking the value before accessing it:
function App () {
const [ladder, setLadder] = useState()
useEffect(() => {
async function fetchMyAPI () {
try {
const res = await axios.get(
'data/wow/pvp-season/27/pvp-leaderboard/3v3?namespace=dynamic-eu&locale=en_US&access_token=12345'
)
setLadder(res)
} catch (error) {
console.log(error)
}
}
fetchMyAPI()
}, [])
return (
<>
{console.log(ladder && ladder.data.bracket)}
{console.log(ladder && ladder.data.entries[0])}
</>
)
}
Notice that I've changed the initial value to undefined
instead of {}
. If you are willing to remain the initial value an empty object for some reason, you can use lodash
(for instance) to check if the object is empty before rendering:
const _ = require('lodash');
return (
<>
{console.log(!_.isEmpty(ladder) && ladder.data.bracket)}
{console.log(!_.isEmpty(ladder) && ladder.data.entries[0])}
</>
)
Upvotes: 1
Reputation: 479
return (
<>
{console.log(ladder?.data?.bracket)}
{console.log(ladder?.data?.entries[0])}
</>
)
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining
You can also use the logical AND operator
return (
<>
{console.log(ladder && ladder.data && ladder.data.bracket)}
{console.log(ladder && ladder.data && Array.isArray(ladder.data.entries) && ladder.data.entries[0])}
</>
)
You can also adapt the initial value of ladder and let the render code unchanged
const [ladder, setLadder] = useState({
data: {
entries: []
}
})
Or even lodash get function!
return (
<>
{console.log(_.get(ladder, "data.bracket"))}
{console.log(_.get(ladder, "data.entries[0]"))}
</>
)
Upvotes: 1