Josh Simon
Josh Simon

Reputation: 259

Having difficulty with nested arrays

I'm working on a react project, and currently trying to access some data within the following nested object:

{name: "Products", attributes: {…}, children: Array(1), value: "", getElementsByTagName: ƒ}

This object is being passed as the prop 'beerList', so in my component, props.beerList.children logs the following to the browser:

[
{name: "Beers", attributes: {…}, children: Array(17), value: "", getElementsByTagName: ƒ}
]

So here's where I'm having trouble. I want to access the array of 17 objects corresponding to the 'children' key in the object above. I tried console.logging props.beerList.children[0], however I got the following error:

Uncaught TypeError: Cannot read property '0' of undefined

I'm not sure why this isn't working - it should return the object containing the array, since the object is at the 0 index of the array. Anyway, here's a more detailed look at the object I'm working with. It's not the complete object, but I'm including it to give an idea of what the overall data structure looks like:

{
  name: 'Products', attributes:{}, value:'', children: [
    {
      name:'Beers', attributes: {}, value: '', children: [
        {
          name: 'Product', attributes:{}, value:'', children: {
            
          }
        }
      ]
    }
  ]
}

Home.js parent component:

class Home extends React.Component {
    constructor() {
        super()
        this.state = {
            beers:[],
            test: 'test'
        }
    }

    componentDidMount() {
        const url = 'http://www.hashigozake.co.nz/taplist.xml'
        const proxyURL = 'https://cors-anywhere.herokuapp.com/'
      
        fetch(proxyURL + url)
        .then(res => res.text())
        .then(beerXML => {
          let beerJs = new XMLParser().parseFromString(beerXML)
          this.setState({
            beers: beerJs
          })
        })
      }

    render() {
    
    return (
        <div className = 'home'>
            <nav className = 'nav'>
                <ul>
                    <Link to = '/about' style={{ textDecoration: 'none' }} >
                        <li className='list'>About</li>
                    </Link>
                    <li className='list'>Food</li>
                    <li className='list'>Events</li>
                    <li className='list'>News</li>
                    <Link to ='/shop' style={{ textDecoration: 'none' }} >
                        <li className='list'>Shop</li>
                    </Link>
                    <li className='list'>Contact</li>
                    <li className='list'>Blog</li>
                </ul>
            </nav>
            <main>
                <div className='main__image'>
                    <img src= {hashi_logo_2}/>
                </div>
                <div>
                    <TileList beerList = {this.state.beers}/>

'TileList' component where fetched data is being mapped over

import React from 'react'
import Tile from './Tile'

const TileList = (props) => {
    console.log(props.beerList.children)
    return (
        <>
         <h1 className = 'h1-pouring'>Currently Pouring:</h1> 
        <div className = 'tile-container'>
            {
                props.beerList.map(item => {
                    return <Tile 
                    />
                })
            } 
        </div> 
        </>
    )
}

export default TileList

Thanks

Upvotes: 0

Views: 58

Answers (1)

Wiktor Bednarz
Wiktor Bednarz

Reputation: 749

You are trying to access beersList when it still doesn't exist. The data is being fetched, so it's an async code. You have to make sure that the data is available when you're trying to access it.

This should fix the error:

{
    this.state.beers && this.state.beers.length > 0 ? (
        <TileList beerList = {this.state.beers}/>
    ) : (
        <span>Fetching data...</span>
    )
}

just replace your <TileList> element call in Home.js with this snippet.

However the solution is crude and would need some more sophisticated loader mechanism. The given hack doesn't cover a case when data is done fetching, but it returned no results.

Upvotes: 1

Related Questions