Aryan Indarapu
Aryan Indarapu

Reputation: 29

React-Google-Maps API: How to search current location for a search result?

I'm trying to build a similar map as on Airbnb, where you can view place markers as you drag the map around. I would like to search for "treatment centers" and place markers using the Google Places API on a map.

I have been using the new, re-written @react-google-maps/api. So far, I was able to create both a search box and an autocomplete and get their latitude and longitude, but both offer only specific locations rather than the most similar searches (ex. if you search Taco Bell on Google Maps, it shows up with several options near you). The code below displays a map with the search box:

import { GoogleMap, LoadScript, Marker, StandaloneSearchBox, Autocomplete } from '@react-google-maps/api';

class HeaderMap extends Component {
  constructor (props) {
    super(props)

    this.autocomplete = null

    this.onLoad = this.onLoad.bind(this)
    this.onPlaceChanged = this.onPlaceChanged.bind(this)

    this.state = {
      currentLocation: {lat: 0, lng: 0},
      markers: [],
      zoom: 8
    }
  }
  

  componentDidMount() {
    navigator?.geolocation.getCurrentPosition(({coords: {latitude: lat, longitude: lng}}) => {
      const pos = {lat, lng}
      this.setState({currentLocation: pos})  
    })
  }

  onLoad (autocomplete) {
    console.log('autocomplete: ', autocomplete)

    this.autocomplete = autocomplete
  }


  onPlaceChanged() {
    if (this.autocomplete !== null) {
      let lat = this.autocomplete.getPlace().geometry.location.lat()
      let long = this.autocomplete.getPlace().geometry.location.lat()
    } else {
      console.log('Autocomplete is not loaded yet!')
    }
  }

  render() {
    return (
      <LoadScript
        googleMapsApiKey="API_KEY_HERE"
        libraries={["places"]}
      >
        <GoogleMap
          id='search-box-example'
          mapContainerStyle={containerStyle}
          center={this.state.currentLocation}
          zoom={14}
          // onDragEnd={search for centers in current location}
        >
          <Marker key={1} position={this.state.currentLocation} />
          <Autocomplete
            onLoad={this.onLoad}
            onPlaceChanged={this.onPlaceChanged}
          >
            <input
              type="text"
              placeholder="Customized your placeholder"
              style={inputStyles}
            />
          </Autocomplete>
        </GoogleMap>
      </LoadScript>
    );
  }
}

How can I automatically search the bounds of the location and get the latitude and longitude of each result based on keywords? Thanks for your help!

Upvotes: 0

Views: 25428

Answers (1)

Pagemag
Pagemag

Reputation: 2977

In your current code, it seems that you are using Autocomplete which was precoded by the library to have the functions of Places Autocomplete. You can use the StandaloneSearchBox to achieve your use case as it is implementing the Places Searchbox which returns a pick list that includes both places and predicted search terms.

Here is the code sample and code snippet below:

/*global google*/
import React from "react";

import { GoogleMap, StandaloneSearchBox, Marker } from "@react-google-maps/api";

let markerArray = [];
class Map extends React.Component {
  state = {
    currentLocation: { lat: 0, lng: 0 },
    markers: [],
    bounds: null
  };

  onMapLoad = map => {
    navigator?.geolocation.getCurrentPosition(
      ({ coords: { latitude: lat, longitude: lng } }) => {
        const pos = { lat, lng };
        this.setState({ currentLocation: pos });
      }
    );
    google.maps.event.addListener(map, "bounds_changed", () => {
      console.log(map.getBounds());
      this.setState({ bounds: map.getBounds() });
    });
  };

  onSBLoad = ref => {
    this.searchBox = ref;
  };

  onPlacesChanged = () => {
    markerArray = [];
    let results = this.searchBox.getPlaces();
    for (let i = 0; i < results.length; i++) {
      let place = results[i].geometry.location;
      markerArray.push(place);
    }
    this.setState({ markers: markerArray });
    console.log(markerArray);
  };

  render() {
    return (
      <div>
        <div id="searchbox">
          <StandaloneSearchBox
            onLoad={this.onSBLoad}
            onPlacesChanged={this.onPlacesChanged}
            bounds={this.state.bounds}
          >
            <input
              type="text"
              placeholder="Customized your placeholder"
              style={{
                boxSizing: `border-box`,
                border: `1px solid transparent`,
                width: `240px`,
                height: `32px`,
                padding: `0 12px`,
                borderRadius: `3px`,
                boxShadow: `0 2px 6px rgba(0, 0, 0, 0.3)`,
                fontSize: `14px`,
                outline: `none`,
                textOverflow: `ellipses`,
                position: "absolute",
                left: "50%",
                marginLeft: "-120px"
              }}
            />
          </StandaloneSearchBox>
        </div>
        <br />
        <div>
          <GoogleMap
            center={this.state.currentLocation}
            zoom={10}
            onLoad={map => this.onMapLoad(map)}
            mapContainerStyle={{ height: "400px", width: "800px" }}
          >
            {this.state.markers.map((mark, index) => (
              <Marker key={index} position={mark} />
            ))}
          </GoogleMap>
        </div>
      </div>
    );
  }
}

export default Map;

Upvotes: 3

Related Questions