使用PlaceID获取地点详细信息

时间:2020-05-10 07:01:58

标签: javascript reactjs google-maps google-maps-api-3 async-await

我设法使用google.maps.places.AutocompleteService()获取了Google地点预测的列表,当我在控制台中打印一项预测时,得到的输出如下:

enter image description here

但是,这个地点信息还不够,因为我想要如下所示的地点信息: enter image description here

现在,通过使用place_id,我已经使用服务google.map.places.PlacesService.getDetails提取了placeetails

predictionSelected = (prediction) => {

    let placeDetails= this.googlePlaces.getDetails(
      { placeId: prediction.place_id },
      function (results, status) {
        console.log(results);
        return results;
      }
    );

    console.log(placeDetails); // results undefined

  }

现在的问题是我无法在getDetails中使用this.state,所以我尝试返回结果。由于getDetails是异步的,所以我无法正确返回结果。

反正在getDetails中使用this.state还是等到响应到来并在异步响应后执行以下操作?

这是我所有的课程

import React from "react";
/* global google */
export default class AddressPredictionsClass extends React.Component {

  constructor(props) {
    super(props);
    this.componentForm = {
      street_number: 'short_name',
      route: 'long_name',
      locality: 'long_name',
      administrative_area_level_1: 'short_name',
      postal_code: 'short_name'
    };
    this.state = {
      street_number: '',
      route: '',
      locality: '',
      administrative_area_level_1: '',
      postal_code: '',
      is_disabled: true,
      is_search_disabled: false,
      predictions: [],
      suggestions: [],
      text: '',
      setIndex: -1

    };
    /** preserve initial state */
    this.baseState = this.state;
    this.autocompleteService = React.createRef();
    this.googlePlaces = '';

    this.onKeyDown = this.onKeyDown.bind(this);

  }

  onKeyDown = (e) => {
            /** some code **/
}

  componentDidMount() {

    if (!this.autocompleteService.current) {
      this.autocompleteService.current = new google.maps.places.AutocompleteService();
    }
    let map = new google.maps.Map(document.createElement('div'));
    this.googlePlaces = new google.maps.places.PlacesService(map);
  }

  getPlacePredictions = (input) => {
    if (input === null) {
      console.log('null input');
      return false;
    }
    var request = {
      input: input,
      componentRestrictions: { country: 'au' },
      types: ["geocode"]
    }
    this.autocompleteService.current.getPlacePredictions(
      request,
      predictions => {
        if (predictions === null) {
          this.setState(
            { predictions: [] }
          )
        } else {
          this.setState(
            { predictions: predictions.map(prediction => prediction) }
          )
        }
      }
    );
  }

  predictionSelected = (prediction) => {

    let placeDetails=this.googlePlaces.getDetails(
      { placeId: prediction.place_id },
      function (results, status) {
        return results;
      }
    );
    console.log(placeDetails);


  }

  changeStateValue(type, val) {
    /** some code **/
    }
}

onChange = (e) => {
         /** some code **/
}

renderSuggestions() {
          /** some code **/
}

  render() {

    return (
      <div>

          <table id="address">
              <tbody>
                  <tr>
                      <td className="">Street address</td>
                      <td className="">
                        <input  onChange={event => this.getPlacePredictions(event.target.value)} className=""/>
                        {this.renderSuggestions()}
                        </td>
                  </tr>

                </tbody>
          </table>
      </div>

  );
  }
}

1 个答案:

答案 0 :(得分:0)

您仍然可以使用this.state进行操作。看看下面的代码:

import React from "react";
import "./styles.css";

/* global google */
export default class App extends React.Component {
  constructor(props) {
    super(props);
    this.componentForm = {
      street_number: "short_name",
      route: "long_name",
      locality: "long_name",
      administrative_area_level_1: "short_name",
      postal_code: "short_name"
    };
    this.state = {
      street_number: "",
      route: "",
      locality: "",
      administrative_area_level_1: "",
      postal_code: "",
      is_disabled: true,
      is_search_disabled: false,
      predictions: [],
      suggestions: [],
      text: "",
      setIndex: -1
    };
    /** preserve initial state */
    this.baseState = this.state;
    this.autocompleteService = React.createRef();
    this.googlePlaces = "";

    this.onKeyDown = this.onKeyDown.bind(this);
  }

  onKeyDown = e => {
    /** some code **/
  };

  componentDidMount() {
    if (!this.autocompleteService.current) {
      this.autocompleteService.current = new google.maps.places.AutocompleteService();
    }
    let map = new google.maps.Map(document.createElement("div"));
    this.googlePlaces = new google.maps.places.PlacesService(map);
  }

  getPlacePredictions = input => {
    if (input === null) {
      console.log("null input");
      return false;
    }
    var request = {
      input: input,
      componentRestrictions: { country: "au" },
      types: ["geocode"]
    };
    this.autocompleteService.current.getPlacePredictions(
      request,
      predictions => {
        if (predictions === null) {
          this.setState({ predictions: [] });
        } else {
          this.setState({
            predictions: predictions.map(prediction => prediction)
          });
          this.predictionSelected(this.state.predictions);
        }
      }
    );
  };

  predictionSelected = predictions => {
    const places = [];
    for (let prediction of predictions) {
      this.googlePlaces.getDetails({ placeId: prediction.place_id }, function (
        place,
        status
      ) {
        places.push(place);
      });
    }
    this.setState({
      ...this.state,
      places: places
    });
  };

  renderSuggestions = () => {
    console.log(
      "predictions",
      this.state.predictions.map(prediction => prediction)
    );
    if (this.state.places && this.state.places.length) {
      console.log("places", this.state.places.map(place => place));
    }
  };

  render() {
    return (
      <div>
        <table id="address">
          <tbody>
            <tr>
              <td className="">Street address</td>
              <td className="">
                <input
                  onChange={event =>
                    this.getPlacePredictions(event.target.value)
                  }
                  className=""
                />
                {this.renderSuggestions()}
              </td>
            </tr>
          </tbody>
        </table>
      </div>
    );
  }
}

这是working codesandbox。确保首先在index.html中添加API密钥。

希望这会有所帮助!