I am building a basic search app with foursquare API using react redux. I am receiving json data but when I try to print address, photos, tips. I am getting an error "Not found" where as I can see everything in console.log
Action.js
export const fetchVenues = (place, location) => dispatch => {
fetch(`https://api.foursquare.com/v2/venues/search?near=${location}&query=${place}&limit=10&client_id=${api_id}&client_secret=${api_key}&v=20180323`)
.then(res => res.json())
.then(data => dispatch({ type: SEARCH_VENUES, payload: data.response.venues}))
.catch(err => console.log(err));
}
export const fetchVenueDetail = (venueId) => dispatch => {
fetch(`https://api.foursquare.com/v2/venues/${venueId}?client_id=${api_id}&client_secret=${api_key}&v=20180323`)
.then(res => res.json())
.then(data => dispatch({ type: FETCH_VENUE, payload: data.response.venue })
)
.catch(err => console.log(err));
}
Reducer.js
const initialState = {
venues: [],
venue: {}
}
const venueReducer = (state= initialState, action) => {
switch(action.type) {
case SEARCH_VENUES:
return {
...state, venues: action.payload
}
case FETCH_VENUE:
return {
...state, venue: action.payload
}
default:
return state;
}
}
Sidebar.js
<aside className="sidebar tips-sidebar">
<h3>Tips</h3>
<ul className="sidebar__list">
{venue.tips.count}
<li className="sidebar__listItem">
<Link to="#" className="sidebar__listItemLink">
<div className="left">
<img src="/image/background.jpg" alt="Tips" className="tips-image" />
</div>
<div className="right">
<h4>Arzu sendag</h4>
<p>guzei mekan cok serdim.</p>
</div>
</Link>
</li>
</ul>
<Link to="#" className="allTips">All Tips</Link>
</aside>;
So my problem is I am receiving the JSON but when I am trying to print address, tips, photos or contact as they are an object. I am receiving the "not found" error.
So i need help for accessing tips, photos object from foursquare venue detail api request.
{Venue.tips} Screenshoot
{Venue.tips.count} Screenshot
You are getting this error because
tips
invenue
object isundefined
until request is done. So, you should add check iftips
property is exists in avenue
object.For example in your RenderSidebar component:
Please notice, that
Sidebar
component not always takevenueTips
object so it's better to use it in a particularcase
.In future, for instance, you can handle
isLoading
state in reducer, and display loading until tips is ready and check this boolean instead oftips
property. It's up to you.Also, don't use
componentWillMount
lifecycle hook for asynchronous operations. UsecomponentDidMount
instead. So, request inComponentDetails
component should be like this:Read the docs for more details. Also, here is working example.