Search code examples
javascriptreactjsgoogle-places-apigoogle-placesgoogle-nearby

Error Missing parameter. You must specify location. (How to addListener for nearbySearch )


I'm trying to save a list of nearby places but through debugging I have realized that the Places services is called before the selected location is assigned. I have tried to look up documentation regarding addListener but I'm very lost because everything relates to the use of a map. However, I only want places. Is there anybody who has faced this problem before?. Any help would be appreciated. This is the code snippet where I try to get NearbyPlaces

  handleSelect = address => {
    geocodeByAddress(address)
    .then(results => getLatLng(results[0]))
    .then(latLng =>   this.state.coordsPair.push(latLng));

    geocodeByAddress(address)
    .then(results => this.state.id.push(results[0].place_id));

    console.log(this.state.id)
    console.log(this.state.coordsPair)
    const {coordsPair} = this.state;
    const {id}= this.state;
    
    let map = new google.maps.Map(document.createElement('div'));
    this.googlePlaces = new google.maps.places.PlacesService(map);

    var request = {
      location: coordsPair[0],
      radius: '500',
      type: ['restaurant']
    };

    
    this.googlePlaces.getDetails(request, callback);

    function callback(results, status) {
      if (status == google.maps.places.PlacesServiceStatus.OK) {
        for (var i = 0; i < results.length; i++) {
          console.log(results[i]);
        }
      }
  }
 
}

The code works for a hardcoded value but when I try to assign a selected value to goes straight to the callback section and gives the error

places_impl.js:72 Uncaught (in promise) Error: Missing parameter. You must specify the location.
    at m$._.t.nearbySearch (places_impl.js:72)

Here is the full code for further reference

import PlacesAutocomplete, {
    geocodeByAddress,
    getLatLng} from 'react-places-autocomplete';

    const google = window.google = window.google ? window.google : {}
class Landing extends Component {
  constructor(props) {
    super(props);
    this.state = { address: '' ,coordsPair: [],formatted_address:[], id: []};
    this.handleSelect = this.handleSelect.bind(this);
    this.handleChange = this.handleChange.bind(this);
  }
 
  handleChange = address => {
    this.setState({ address });

    
    geocodeByAddress(address)
    .then(results => console.log(results[0]));
  };
 
  handleSelect = address => {
    geocodeByAddress(address)
    .then(results => getLatLng(results[0]))
    .then(latLng =>   this.state.coordsPair.push(latLng));

    geocodeByAddress(address)
    .then(results => this.state.id.push(results[0].place_id));

    console.log(this.state.id)
    console.log(this.state.coordsPair)
    const {coordsPair} = this.state;
    const {id}= this.state;
    
    let map = new google.maps.Map(document.createElement('div'));
    this.googlePlaces = new google.maps.places.PlacesService(map);

    var request = {
      location: coordsPair[0],
      radius: '500',
      type: ['restaurant']
    };

    
    this.googlePlaces.getDetails(request, callback);

    function callback(results, status) {
      if (status == google.maps.places.PlacesServiceStatus.OK) {
        for (var i = 0; i < results.length; i++) {
          console.log(results[i]);
        }
      }
  }
 
}


  render() {
    return (
      <PlacesAutocomplete
        value={this.state.address}
        onChange={this.handleChange}
        onSelect={this.handleSelect}
      >
        {({ getInputProps, suggestions, getSuggestionItemProps, loading }) => (
          <div>
            <input
              {...getInputProps({
                placeholder: 'Search Places ...',
                className: 'location-search-input',
              })}
            />
            <div className="autocomplete-dropdown-container">
              {loading && <div>Loading...</div>}
              {suggestions.map(suggestion => {
                const className = suggestion.active
                  ? 'suggestion-item--active'
                  : 'suggestion-item';
                // inline style for demonstration purpose
                const style = suggestion.active
                  ? { backgroundColor: '#fafafa', cursor: 'pointer' }
                  : { backgroundColor: '#ffffff', cursor: 'pointer' };
                return (
                  <div
                    {...getSuggestionItemProps(suggestion, {
                      className,
                      style,
                    })}
                  >
                    <span>{suggestion.description}</span>
                  </div>
                );
              })}
            </div>
          </div>
        )}
      </PlacesAutocomplete>
    );
  }
}


Solution

  • You are not waiting for the first two methods to finish to call the third. If you use then() catch(), you should put your logic inside the then() callback to have it defined. Else you can use await

    change it to:

       handleSelect = async address => {
          let results = await  geocodeByAddress(address)
          let latLng = await getLatLng(results[0]);
          this.state.coordsPair.push(latLng);
    
          let codeResults = await geocodeByAddress(address)
          this.state.id.push(codeResults[0].place_id)
    
          console.log(this.state.id)
          console.log(this.state.coordsPair)
          const {coordsPair} = this.state;
          const {id}= this.state;
        
          let map = new google.maps.Map(document.createElement('div'));
          this.googlePlaces = new google.maps.places.PlacesService(map);
    
          var request = {
          location: coordsPair[0],
          radius: '500',
          type: ['restaurant']
        };