Ravenous part 4 bad request

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

Hello,
I am having a problem similar to other people have had on the forums but I am going goggle eyed trying to make sense of this problem. I think it’s time to ask for some help with my code.
I get this problem:

TypeError: Cannot read property ‘map’ of undefined

Here is my code:
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 business={business} key={business.id} />;
      })
    }
     </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.handleTermChange = this.handleTermChange.bind(this);
    this.handleLocationChange = this.handleLocationChange.bind(this);
    this.handleSearch = this.handleSearch.bind(this);
    this.handleSortByChange = this.handleSortByChange.bind(this);

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

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

    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();
    }


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


  render(){
    return(
      <div className="SearchBar">
        <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;

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 = {
      businesses: [],
    };
    this.searchYelp = this.searchYelp.bind(this);
  }
  searchYelp(term, location, sortBy){
    Yelp.search(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;

Business.js

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

class Business extends React.Component {
  render (){
    return (
      <div className="Business">
        <div className="image-container">
          <img src={this.props.business.imageSrc} alt=''/>
        </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;

Yelp.js

const apiKey = '63h9DgR-UVHpSuojUZ2uGSZdhOv-hkA3_u41bYIp5mBwEEVT_mn15p6fdzfFdy5o3UxKkCcOoKdEhf6nOX8Gb1UBH8wHMF4ZA-rqQGzKhpSvQ3inBxjqPlbfPuOXnYx';



const Yelp = {
  search(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 => ({
        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.title,
        rating: business.rating,
        reviewCount: business.review_count
        }));
      }
    });
  }
};

export default Yelp;

Many thanks in advance of any help or advice!!

Hey em. Check if your App state array is updating. The JsonResponse map method is not returning anything and has an extra set of parentheses. Here is an excerpt to validate your code with:

then(jsonResponse => {
      if(jsonResponse.businesses) { //Check if response is valid by making sure it has a businesses key
        return jsonResponse.businesses.map((business) => {
          return { //Object with valid values
            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,
          }
        });
      };
    })

Hello CxSG,
Thanks for your reply to my problem.
I have added the extra return and {}'s as suggested in your excerpt. However, I still am getting this error -
TypeError: Cannot read property ‘map’ of undefined in the BusinessList.render.
Any clues to what may be wrong?

BusinessList.render

Hi, two thing i notice in your buisness list js
1)you are missing a (
2) not sure if this makes a difference but we have the id fliped


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

Yelp returns error when it cant find the location you are searching for.
Yelp.js should do error handling. Error handling should be a part of the project. It works when you search locations that Yelp knows about and fails miserbly when it doesnt. A lot of queries here about Ravenous 4 are because the project doesnt do error handling in the react components.

1 Like

Hi all was the solution found to this problem as I’m having the exact same issue. I’ve triple checked my code against the solution code and it’s all ‘correct’ but still getting the same error. Help! :joy:

Have you checked that the response you get from the Yelp API is what you’re expecting?

Using console.log() to check that you’re getting what you should be, before attempting to manipulate it, might show you your error.

Hi, sorry for my ignorance but do you know exactly where the console.log() would need to go to check this? Assuming you have access to the solution code as you’re Help Desk?

I’m not Codecademy staff; I don’t have any special access, the “Help Desk” thing is based purely off other people marking my posts as a “solution” here on the forums. :slight_smile:

Don’t take this the wrong way, but I’m not going to give you the precise answer because figuring out how to debug your code is an important skill.

I’ll give you a nudge in the right direction, though.

In the function that you’ve written to search Yelp, you’re chaining a call to fetch() and several uses of .then().

You can strategically insert calls to console.log() throughout this chain to watch what is going on. There’s one particular .then() which, if you’re getting the same error (Cannot read property 'map' of undefined), should jump out at you for monitoring in this way… but feel free to add calls to console.log() throughout the chain to watch the progress of your program. :slight_smile:

Ah, I see thanks very much for your help. I’ll give it a whirl and see how I go.

1 Like

No worries.

If you’re confident your code is right, then watching what you’re getting back from the Yelp API would be my first stop in troubleshooting.

If you still can’t get to the bottom of it after throwing a load of console.log() into the process, let us know and we’ll take another look. At that point, though, we’d need your code to look at which you can share either through something like a Gist/GitHub repo or by posting directly here on the forums.

There’s a guide to posting code, with the right formatting etc, available here.

I got it to work by finding a workaround on Youtube. Thanks for your help! I need to brush up on my error handling skills.

1 Like