Jerlam
Jerlam

Reputation: 1101

How to get axios response properly in react?

I am trying to fetch data with axios for a search bar functionality, but I can't have it working. When I console log de reponse IN the searchForPlaces function below I get the reponse, however I get undefined when i call it in my App.

Here is my function to get data, which is located in my utils.js:

export function searchForPlaces(dataToSearch) {
  const requestUrl = `https://api.mapbox.com/geocoding/v5/mapbox.places/${dataToSearch}.json?access_token=${accessToken}`;

  const result = axios
    .get(requestUrl)
    .then(response => {
      return response;
    })
    .catch(error => {
      return error;
    });
}

Here is the code:

class App extends React.Component {
  renderSearchedPlaces() {
    console.log("render");
    return (
      <div>
        {this.state.searchForPlacesResponse.data.features.forEach(place => {
          return <div>{place}</div>;
        })}
      </div>
    );
  }

  querySearchForPlaces() {
    this.searchInputTimeout ? clearTimeout(this.searchInputTimeout) : null;

    console.log(searchForPlaces(this.state.searchInputValue));
    this.searchInputTimeout = setTimeout(
      function() {
        let searchForPlacesResponse = searchForPlaces(
          this.state.searchInputValue
        );

        this.setState({ searchForPlacesResponse });
      }.bind(this),
      400
    );
  }

  renderContent(item) {
    if (item === "share") {
      return (
        <React.Fragment>
          <h2>
            Share with your friends the places that you like(d), or
            dislike(d)...
          </h2>
          <div className="search-nearby">
            <div
              className={
                this.state.searchNearby === "search"
                  ? "search selected"
                  : "search"
              }
              onClick={() => {
                this.state.searchNearby === "search"
                  ? null
                  : this.setState({ searchNearby: "search" });
              }}
            >
              Search
            </div>
            <div
              className={
                this.state.searchNearby === "nearby"
                  ? "nearby selected"
                  : "nearby"
              }
              onClick={() => {
                this.state.searchNearby === "nearby"
                  ? null
                  : this.setState({ searchNearby: "nearby" });
              }}
            >
              Nearby
            </div>
          </div>
          <input
            className="search-input"
            type="text"
            placeholder="Search a place"
            value={this.state.searchInputValue}
            onChange={e => this.setState({ searchInputValue: e.target.value })}
            onKeyUp={() => this.querySearchForPlaces()}
          />
          {this.state.searchForPlacesResponse
            ? this.renderSearchedPlaces()
            : null}
        </React.Fragment>
      );
    }
  }

  // ...
}

Upvotes: 2

Views: 3934

Answers (1)

Tholle
Tholle

Reputation: 112917

The axios request is asynchronous, so your searchForPlacesResponse will be undefined.

You can instead return the axios request, and use then in querySearchForPlaces to wait for the promise to resolve before using setState.

export function searchForPlaces(dataToSearch) {
  const requestUrl = `https://api.mapbox.com/geocoding/v5/mapbox.places/${dataToSearch}.json?access_token=${accessToken}`;

  return axios
    .get(requestUrl)
    .then(response => {
      return response.data;
    })
    .catch(error => {
      console.error(error);
    });
}

class App extends React.Component {
  // ...

  querySearchForPlaces() {
    this.searchInputTimeout ? clearTimeout(this.searchInputTimeout) : null;

    console.log(searchForPlaces(this.state.searchInputValue));
    this.searchInputTimeout = setTimeout(() => {
      searchForPlaces(this.state.searchInputValue)
        .then(searchForPlacesResponse => {
          this.setState({ searchForPlacesResponse });
        });
    }, 400);
  }

  // ...
}

Upvotes: 3

Related Questions