Search code examples
reactjstypescriptgoogle-mapsgeolocationgeocoding

Google maps create marker with geolocations


Using react i'm trying to create a google maps with markers, that apply to an address instead of lat/lng values. As you can see the component creates a script tag when mounted and initializes map and marker through the google.maps... functions. If i create a marker with lat/lng it works fine, but instead i want to search by address. So here's my code, can you find the bug? I'm not using any packages and would also like to stick to that. (NO PACKAGES!) Another question would be in what format i have to write those addresses. Street, Postalcode, city?

Stack overflow wants some more text so sorry for repeating myself.

export interface ProjectsListMapProps {
}

export default class ProjectsListMap extends React.Component<ProjectsListMapProps> {
  constructor(props: ProjectsListMapProps) {
    super(props);
    this.renderMap = this.renderMap.bind(this);
    this.mapContainer = this.mapContainer.bind(this); 
    this.codeAddress = this.codeAddress.bind(this);
  }

  componentDidMount() {
    if (!document.querySelectorAll(`[src="${'https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY'}"]`).length) { 
      document.body.appendChild(Object.assign(
        document.createElement('script'), {
          type: 'text/javascript',
          src: 'https://maps.googleapis.com/maps/api/js',
          onload: () => this.renderMap()
        }
      ));
    }
  }

  renderMap() {
    const coords = { lat: 41.375885, lng: 2.177813 };
    const el = document.getElementById('map');
    if (el) {
      const map = new google.maps.Map(el, {
        zoom: 16,
        center: {
          lat: coords.lat,
          lng: coords.lng
        }
      });
      const geocoder = new google.maps.Geocoder();
      this.codeAddress(geocoder, map);
      return map;
    }
    else {
      return null;
    }
  }

  codeAddress(geocoder: any, map: any) {
    geocoder.geocode({'address': 'Budapest'}, function(results: any, status: any) {
      console.log(results);

      if (status === 'OK') {
        map.setCenter(results[0].geometry.location);
        const marker = new google.maps.Marker({
          map: map,
          position: results[0].geometry.location
        });
        return marker;
      } 
      else {
        return null;
      }
    });
  } 

  render() {
    return(
      <div className="card map-holder">
        <div id="map" />
      </div>
    );
  }
}

My Log returns an empty array as a result.

Check out: https://codepen.io/mblmarlon/pen/PoqzjXy for an example


Solution

  • It looks like your code is using Google Maps JavaScript Geocoding service and not Geolocation.

    Upon checking it seems that Geocoding service is working properly now however you are still hardcoding the value of your address in the code. To help you further, I tweak your code and added text input field for your address. Here is the sample code.

    
    var map;
    class BookSlider extends React.Component {
      constructor(props) {
        super(props);
        this.renderMap = this.renderMap.bind(this);
        this.handleInputChange = this.handleInputChange.bind(this);
        this.handleClick = this.handleClick.bind(this);
        this.state = {
          input: ""
        };
      }
    
      componentDidMount() {
        // ADD API KEY HERE
        if (
          !document.querySelectorAll(
            `[src="${"https://maps.googleapis.com/maps/api/js?key=API_KEY"}"]`
          ).length
        ) {
          document.body.appendChild(
            Object.assign(document.createElement("script"), {
              type: "text/javascript",
              // ADD API KEY HERE
              src:
                "https://maps.googleapis.com/maps/api/js?key=API_KEY",
              onload: () => this.renderMap()
            })
          );
        }
      }
    
      renderMap() {
        const coords = { lat: 41.375885, lng: 2.177813 };
        const el = document.getElementById("map");
    
        if (el) {
          map = new google.maps.Map(el, {
            zoom: 16,
            center: {
              lat: coords.lat,
              lng: coords.lng
            }
          });
    
          return map;
        } else {
          return null;
        }
      }
    
      handleInputChange(event) {
        const target = event.target;
        const value = target.type === "checkbox" ? target.checked : target.value;
        const name = target.name;
    
        this.setState({
          [name]: value
        });
      }
    
      handleClick(event) {
        const geocoder = new google.maps.Geocoder();
        this.codeAddress(geocoder);
        event.preventDefault();
      }
    
      // THIS CRASHES if you comment it out //
    
      codeAddress(geocoder) {
        var address = this.state.input;
        geocoder.geocode({ address: address }, function(results, status) {
          console.log(results);
          if (status === "OK") {
            map.setCenter(results[0].geometry.location);
            const marker = new google.maps.Marker({
              map: map,
              position: results[0].geometry.location
            });
            return marker;
          } else {
            return null;
          }
        });
      }
    
      render() {
        return (
          <section className="partial-book-slider">
            <h1>ADD YOUR API KEY TO MAKE IT WORKIN</h1>
            <input
              id="input"
              name="input"
              value={this.state.input}
              onChange={this.handleInputChange}
            />
            <button id="submit" onClick={this.handleClick}>
              {" "}
              Search
            </button>
    
            <div className="card map-holder">
              <div id="map" />
            </div>
          </section>
        );
      }
    }
    /*
     * Render the above component into the div#app
     */
    React.render(<BookSlider />, document.getElementById("app"));