Skip to content

Data defined, but return undefined

import { useState , useEffect} from "react";
import 'semantic-ui-css/semantic.min.css'
import { Header, Button , Container, Image} from 'semantic-ui-react'
import dotalLogo from './dota2.png'

import React from "react";
import Loading from './loading'
const dataUrl = 'https://api.opendota.com/api/heroStats'

function App() {
 const [loading, setLoading] = useState(false)
 const [data, setData] = useState([])
 const [index, setIndex] = useState(0)

 const fecthApi = async () => {
   setLoading(true)
   try {
     const fetched = await fetch(dataUrl)
     const parsed = await fetched.json()
     setData(parsed)
     setLoading(false)
  
   } catch (error) {
     console.log('error')
     setLoading(false)
   }
 }

 useEffect(()=>fecthApi(),[])
 if (loading){
    return <Loading />
  }

  function nextBtn(e) {
    e.preventDefault()
    setIndex((prev)=>prev+1)
  }

  function backBtn(e) {
    e.preventDefault()
    setIndex((prev)=>prev-1)
  }

  return (
    <>
      <main id="main-content">
        <Container>
          <Header className='headings' as='h1' size='medium' style={{fontSize: 40}}>
            <img className="dota-logo" src={dotalLogo} alt="" />
            <Header.Content className="dota-header">Dota 2</Header.Content>
          </Header>
          <br />
          <Container className='middle-layer'>

            <Button 
              onClick={(e)=> nextBtn(e)} 
              className='change-btn-one' 
              content='Back' 
              icon='arrow left' 
              labelPosition='left' />

            <Image 
              className='dota-img' 
              src={"https://api.opendota.com" + data[index].img} 
              rounded
              alt='err' 
              bordered 
              centered/>

            <Button 
              onClick={(e)=> backBtn(e)} 
              className='change-btn-two' 
              content=' Next ' 
              icon='arrow right' 
              labelPosition='right' />

          </Container>
            </Container>
            <Container>
              <p>{data[index].localized_name}</p>
                </Container>
            <div className="contain"></div>
          </main>
        </>
      );
    }

export default App;

I get an error after compiling it img but I have defined it and fetch the data using async await but get a

TypeError: data[index] is undefined

I have stuck for several hours and still come out with no solution. Furthermore, I have tried to destructed it but still get the same error. Using data.map() works, but I only want to display one hero data at a time, and using map would load 120 hero data.

I understand this is kinda a dumb question, but I just can’t figure it out 🙂

Answer

data[index] is undefined before fetching ended. So, data[index].localized_name will gives you error. you can write it like this.

data[index] && data[index].localized_name