My parent component shows an error about my props:
Warning: Failed prop type: The prop
prop name here
is marked as required inParentComponent
, but its value isundefined
.
The values are not undefined though.
When I remove isRequired from my PropTypes I get the error:
'Type Error: this.state is undefined'
But again my state is defined above.
I am new to react and javascript in general, any help is appreciated :)
I thought maybe it was because I was using arrow functions, so i switched to regular functions and bind them in the constructor but that didn't work. The code worked when it wasn't separated into components like it is now. What am I doing wrong here guys?
import PropTypes from 'prop-types';
import apiKey from '../config/apiKey'
import SearchForm from './SearchForm'
import SearchResults from './SearchResults'
import Details from './Details'
class ParentComponent extends React.Component {
constructor(props) {
super(props)
this.state = {
term: '',
location: '',
isLoading: false,
businesses: [],
business: {}
}
}
handleChange = (event) => {
const { name, value } = event.target;
this.setState({
[name]: value
})
}
// Get data based on search term and location
handleSubmit = (event) => {
event.preventDefault();
const term = this.state.term;
const location = this.state.location;
this.setState({
isLoading: true
});
fetch(`https://cors-anywhere.herokuapp.com/https://api.yelp.com/v3/businesses/search?term=${term}&location=${location}`,
{
headers: { 'Authorization': `Bearer ${apiKey}` }
})
.then(response => response.json())
.then(response => {
const Businesses = response.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.title,
rating: business.rating,
reviewCount: business.review_count
}
});
return this.setState({
businesses: Businesses,
isLoading: false
});
})
.catch(err => console.log(err))
};
BusinessList = this.state.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.title,
rating: business.rating,
reviewCount: business.review_count
}
})
// Get detail data from business based on id extracted from previous fetch request
getDetails = () => {
return fetch(`https://cors-anywhere.herokuapp.com/https://api.yelp.com/v3/businesses/${this.BusinessList.id}`,
{
headers: { 'Authorization': `Bearer ${apiKey}` }
})
.then(response => response.json())
.then(response => {
const data = {
id: response.id,
alias: response.alias,
name: response.name
}
this.setState({
business: data
});
})
.catch(err => console.log(err))
};
render() {
return (
<div>
<SearchForm
handleSubmit={this.handleSubmit}
handleChange={this.handleChange}
term={this.state.term}
location={this.state.location}
/>
<SearchResults
key={this.BusinessList.id}
id={this.BusinessList.id}
imageSrc={this.BusinessList.imageSrc}
name={this.BusinessList.name}
address={this.BusinessList.address}
city={this.BusinessList.city}
state={this.BusinessList.city}
zipCode={this.BusinessList.zipCode}
category={this.BusinessList.category}
rating={this.BusinessList.rating}
reviewCount={this.BusinessList.reviewCount}
/>
<Details
key={this.business.id}
id={this.business.id}
alias={this.business.alias}
name={this.business.name}
/>
</div>
);
};
};
ParentComponent.propTypes = {
term: PropTypes.string.isRequired,
location: PropTypes.string.isRequired,
isLoading: PropTypes.bool.isRequired,
businesses: PropTypes.array.isRequired,
business: PropTypes.object.isRequired
}
export default ParentComponent;