Foursquare Api - Unable to print json data

2019-09-01 15:33发布

问题:

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

回答1:

You are getting this error because tips in venue object is undefined until request is done. So, you should add check if tips property is exists in a venue object.

For example in your RenderSidebar component:

case "tips":

    // check if tips is exists in venueTips object
    // else make it empty to avoid error
    const { tips = {} } = venueTips

    template = <aside className="sidebar tips-sidebar">
        <h3>Tips</h3>
        <ul className="sidebar__list">
          {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>;
    break;

Please notice, that Sidebar component not always take venueTips object so it's better to use it in a particular case.

In future, for instance, you can handle isLoading state in reducer, and display loading until tips is ready and check this boolean instead of tips property. It's up to you.

Also, don't use componentWillMount lifecycle hook for asynchronous operations. Use componentDidMount instead. So, request in ComponentDetails component should be like this:

componentDidMount() {
    this.props.fetchVenueDetail(this.props.match.params.id);
}

Read the docs for more details. Also, here is working example.