Ravenous Part 4 - debugging

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

Not sure why I’m getting this error code!

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

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

export default BusinessList;
1 Like

Hello, @method6453649862. Welcome to the forums.

So, the error message says, cannot read property 'map' of undefined. Where are you using ‘map’?

The message is saying that the object that you are trying to access the ‘map’ property of is undefined, so we need to look at where it was supposed to be defined, and determine why it isn’t.

I am using the map function in my BusinessList component

I followed the example videos exactly so I’m not sure why I’m getting this error

This is my App component where businesses is being rendered

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= {
      business: [],
    };

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

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

export default App;
1 Like

Okay, so what is the name of the object that is undefined? Does the object exist? (Is it defined?)
If we look at the line of code where you try to access ‘map’:

this.props.businesses.map(function(business, i)

Then we look at the props in your App component:

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

Is there a prop named businesses? :wink:

There is another issue here:

I made some changes, but still no fix. It must be something small that I can’t see. I feel like I have combed over everything multiple times!

App.js

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 = {
      business: [],
    };

    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;

Yelp.js

const apiKey='MJhN1iVFiA__KzcBk6LhC7jnnhKAMEjbJw7z7OOthxb7J34RfPztfGWKfm1Uxrl-g0w-DW8sNjZTw1xux0tCwCANqPIYbABPOpuCTFYc-5ZW59lmCPGnxWMZ3_hPXnYx';

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 => {
              return {
                id: business.id,
                imageSrc: business.image_url,
                name: business.name,
                address: business.location.address1,
                city: business.location.city,
                state: business.location.state,
                zipCode: business.location.zip_code,
                category: business.categories[0].title,
                rating: business.rating,
                reviewCount: business.review_count
              };
            });
          }
        });
    }
  };
  
  export default Yelp;

Business.js


class Business extends React.Component {
    render() {
        return (
            <div className="Business">
                <div className="image-container">
                    <img src={this.props.business.imageSrc} alt={this.props.business.name}/>
                </div>
                <h2>{this.props.business.name}</h2>
                <div className="Business-information">
                    <div className="Business-address">
                        <p>{this.props.business.address}</p>
                        <p>{this.props.business.city}</p>
                        <p>{this.props.business.state}, {this.props.business.zipCode}</p>
                    </div>
                    <div className="Business-reviews">
                        <h3>{this.props.business.category}</h3>
                        <h3 className="rating">{this.props.business.rating} stars</h3>
                        <p>{this.props.business.reviewCount} reviews</p>
                    </div>
                </div>
            </div>
        );
    }
}

export default Business;

BusinessList.js

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;

SearchBar.js

import React from "react";
import "./SearchBar.css";


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

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

  getSortByClass(sortByOption) {
    if (this.state.sortBy === sortByOption) {
      return "active";
    } 
    return "";
    //this.state.sortBy === sortByOption ? "active" : ""; -> raises ESLint error, can be fixed w/ if/else statement or disabling no-unused-expressions
  }

  handleSortByChange = (sortByOption) => {
    this.props.searchYelp(this.state.term, this.state.location, sortByOption);
    this.setState({sortBy: sortByOption});
  }

  handleTermChange = (e) => {
    this.setState({term: e.target.value});
  }

  handleLocationChange = (e) => {
    this.setState({location: e.target.value});
  }

  handleSearchClick = (e) => {
    this.props.searchYelp(this.state.term, this.state.location, this.state.sortBy);
    e.preventDefault(); //to prevent the default action of clicking a link from triggering at the end of the method
  }

  handleSearchEnter = (e) => {
    if (e.key === "Enter") {
      this.props.searchYelp(this.state.term, this.state.location, this.state.sortBy);
      e.preventDefault();
    }
  }

  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" onKeyPress={this.handleSearchEnter}>
        <div className="SearchBar-sort-options">
          <ul>
            {this.renderSortByOptions()}
          </ul>
        </div>
        <div className="SearchBar-fields">
          <input onChange={this.handleTermChange} placeholder="Search Businesses" />
          <input onChange={this.handleLocationChange} placeholder="Where?" />
        </div>
        <div className="SearchBar-submit">
          <a onClick={this.handleSearchClick} href="foo" >Let's Go</a>
        </div>
      </div>
    )
  }
}

export default SearchBar;

I am also getting this error in my index.js

This still isn’t corrected.


class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      business: [], //should be businesses
    };

Beyond that will have to wait till I have more time.

Oh I see. Thank you, it worked!

1 Like