Ravenous Part 4

https://www.codecademy.com/paths/web-development/tracks/front-end-applications-with-react/modules/ravenous-part-four/projects/interacting-with-yelp-api

Hi all I keep getting this error. any help would be appreciated.

TypeError: Cannot read property 'map' of undefined
BusinessList.render
C:/Users/dan_g/OneDrive/Documents/Codecademy/ravenous/src/components/BusinessList/BusinessList.js:8
   5 | class BusinessList extends React.Component {
   6 |     render () {
   7 |         return (
>  8 |             <div className="BusinessList">
   9 |                 {
  10 |                     this.props.businesses.map(business => {
  11 |                         return <Business key={business.id} business={business} />;
View compiled
▶ 18 stack frames were collapsed.
(anonymous function)
C:/Users/dan_g/OneDrive/Documents/Codecademy/ravenous/src/components/App/App.js:20
  17 | }
  18 | searchYelp(term, location, sortBy){
  19 |   Yelp.searchYelp(term, location, sortBy).then((businesses) => {
> 20 |     this.setState({businesses: this.props.businesses});
     | ^  21 |   });
  22 | }
  23 | 
import React from 'react';
import './App.css';
import BusinessList from '../BusinessList/BusinessList';
import SearchBar from '../SearchBar/SearchBar';
import Yelp from '../../util/Yelp';


class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      businesses: this.props.businesses,
    };

    this.searchYelp = this.searchYelp.bind(this);

  }
  searchYelp(term, location, sortBy){
    Yelp.searchYelp(term, location, sortBy).then((businesses) => {
      this.setState({businesses: businesses});
    });
  }

  render(){
    return (
      <div className="App">
        <h1>Ravenous</h1>
        <SearchBar searchYelp={this.searchYelp}/>
        <BusinessList businesses={this.state.businesses}/> 
      </div>
    );
  }
  
}

export default App;

import React from 'react';
import './BusinessList.css';
import Business from '../Business/Business';

class BusinessList extends React.Component {
    render () {
        return (
            <div className="BusinessList">
                {
                    this.props.businesses.map(business => {
                        return <Business key={business.id} business={business} />;
                    })
                }
            </div>
        )
    }
}

export default BusinessList;
const apiKey = "q0CtU8ZMPqCdq112PWHGhfaqjIokWc0B-K40N_IEcUnXh4caQuppeig8pmWa9YLY7YOUHti1xlHjxIuhngjJ5YChImXtfXFp8T44IeTREtqMDk-6jH7go5SUaWA1X3Yx";

const Yelp = {
    searchYelp(term, location, sortBy){
        return fetch(`https://cors-anywhere.herokuapp.com/https://api.yelp.com/v3/businesses/search?term=${term}&location=${location}&sort_by=${sortBy},`, {
            headers: {
                Authorization: `Bearer ${apiKey}`,
            }
        }).then ((response) => {
            return response.json();
        }).then((jsonResponse) => {
            if (jsonResponse.businesses) {
                return jsonResponse.businesses.map((business) => {
                    console.log(business);
                    return {
                        id: business.id,
                        imgSrc: business.image_url,
                        name: business.name,
                        address: business.location.address1,
                        city: business.location.city,
                        state: business.location.state,
                        zipCode: business.location.zipCode,
                        category: business.categories[0].title,
                        rating: business.rating,
                        reviewCount: business.review_count,
                    };
                });
            }
        }) 
    }
};

export default Yelp;
import React from 'react';
import './Business.css';



class Business extends React.Component {
    render() {
        const { business } = this.props;
        return (
            <div className="Business">
                <div className="image-container">
                    <img src='https://s3.amazonaws.com/codecademy-content/programs/react/ravenous/pizza.jpg' alt=''/>
                </div>
                <h2>{business.name}</h2>
                <div className="Business-information">
                <div className="Business-address">
                    <p>{business.address}</p>
                    <p>{business.city}</p>
                    <p>{business.state}{business.zipCode}</p>
                </div>
                <div className="Business-reviews">
                    <h3>{business.category}</h3>
                    <h3 className="rating">{business.rating}</h3>
                    <p>{business.reviewCount}</p>
                </div>
                </div>
            </div>
        )
    }
};

export default Business;
import React from 'react';
import './SearchBar.css';



class SearchBar extends React.Component {
    constructor(props){
        super(props);
        this.state = {
            term: "",
            location: "",
            sortBy: "best_match",
        };

        this.handleTermChange = this.handleTermChange.bind(this);
        this.handleLocationChange = this.handleLocationChange.bind(this);
        this.handleSearch = this.handleSearch.bind(this);

        this.sortByOptions = {
            'Best Match': 'best_match',
            'Highest Rated': 'rating',
            'Most Reviewed': 'review_count'
        }
    }

    handleSortByChange(sortByOption){
        this.setState({ sortBy: sortByOption });
    }

    handleTermChange(event){
        this.setState({ term: event.target.value });
    }

    handleLocationChange(event){
        this.setState({ location: event.target.value });
    }

    handleSearch(event){
        this.props.searchYelp(this.state.term, this.state.location, this.state.sortBy);
        event.preventDefault();
    }

    getSortByClass(sortByOption){
        if (sortByOption === this.state.sortBy){
            return "active";
        } else {
            return "";
        }
    }

    renderSortByOptions() {
        return Object.keys(this.sortByOptions).map(sortByOption => {
            let sortByOptionValue = this.sortByOptions[sortByOption];
            return <li key={sortByOptionValue} onClick={this.handleSortByChange.bind(this, sortByOptionValue)} className={this.getSortByClass(sortByOptionValue)}> {sortByOption} </li>;
        });
    }

    
    render() {
        return (
            <div className="SearchBar" searchYelp={this.searchYelp}>
                <div className="SearchBar-sort-options">
                    <ul>
                        {this.renderSortByOptions()}
                    </ul>
                </div>
                <div className="SearchBar-fields">
                    <input placeholder="Search Businesses" onChange={this.handleTermChange}/>
                    <input placeholder="Where?" onChange={this.handleLocationChange}/>
                </div>
                <div className="SearchBar-submit">
                    <a href = "www.#.com" onClick={this.handleSearch}>Let's Go</a>
                </div>
            </div>
        )
    }
}

export default SearchBar;
TypeError: Cannot read property 'map' of undefined
BusinessList.render
C:/Users/dan_g/OneDrive/Documents/Codecademy/ravenous/src/components/BusinessList/BusinessList.js:8
   5 | class BusinessList extends React.Component {
   6 |     render () {
   7 |         return (
>  8 |             <div className="BusinessList">
   9 |                 {
  10 |                     this.props.businesses.map(business => {
  11 |                         return <Business key={business.id} business={business} />;

The error would suggest that the businesses prop being passed to your BusinessList component is empty (undefined).

Review the parts of your code which are involved in setting this value (it’s part of the App state).

Try it yourself first, but if you get really stuck...

I think the error is your comma in the fetch() to the Yelp API…

1 Like

Hi mate,

Still cant find it. Even with checking through the provided ‘complete’ code.

Don’t think the comma’s the issue as it separates the url and the headers: object. When I take it out nothing happens and VSCode gives me a red squiggly.

nope youre right I see it

still doesn’t get rid of the error though

Ah, sorry, I missed another error. I’ve answered topics about this error so many times recently where the issue was in Yelp.js that I immediately check it.

I am presuming that you get the error as soon as you try and load the page (or run npm start on the terminal, if you’re working locally)?

The issue is with the starting state for the App component. You should see the error pretty quickly, but if not let me know. :slight_smile:

1 Like

I just can’t see it.

Is it something to do with

this.state = {
      businesses: this.props.businesses,
    }

Is has to be an empty object?

I’ll answer your question with another question.

The code below features in your App component, as part of App.js.

this.state = {
      businesses: this.props.businesses,
    }

Where does the App component have a prop passed in called businesses? At the point in time that your React app starts up, what value does this.props.businesses have in the context of the App component?

An empty array is a logical choice for the initial state, as you have yet to query Yelp and get the data to populate the business list… but you can have the initial state be anything that the map() function can be called against. :slight_smile:

1 Like

Yep I meant empty array not object :man_facepalming:

I really appreciate the help, truly.

1 Like

Well, really, everything in JavaScript is ultimately an object. :slight_smile:

No problem. :slight_smile: The Ravenous project was a good one, it brings quite a bit of knowledge together over several lessons. If that’s the first bit where you got properly stuck, that’s not bad going. :+1:

If you get stuck with anything else, pop back and ask us. We’ll do what we can to help. :smiley:

1 Like