title: Google Places Autocomplete React Component
body: <p>I'm learning react and trying to create a Google places autocomplete component, inside a rails app the using react on rails gem. Here's what I have so far, need some help finishing it off.</p>
  
  <p>I think I'm having an issue getting the Google javascript library to load correctly.  See error message from console below (note I have the proper [KEY] running in my app).   </p>
  
  <pre><code>Navigated to https://react-on-rails-basic-tutorial-mcl282.c9users.io/
  js?key=[KEY]&amp;libraries=places&amp;callback=initAutocomplete:102 Uncaught Yc {message: "initAutocomplete is not a function", name: "InvalidValueError", stack: "Error↵    at new Yc (https://maps.googleapis.com/m…libraries=places&amp;callback=initAutocomplete:139:73"}
  Yg @ js?key=[KEY]&amp;libraries=places&amp;callback=initAutocomplete:102
  (anonymous) @ js?key=[KEY]&amp;libraries=places&amp;callback=initAutocomplete:139
  google.maps.Load @ js?key=[KEY]&amp;libraries=places&amp;callback=initAutocomplete:21
  (anonymous) @ js?key=[KEY]&amp;libraries=places&amp;callback=initAutocomplete:138
  (anonymous) @ js?key=[KEY]&amp;libraries=places&amp;callback=initAutocomplete:139
  createReactElement.js?74ab:40 RENDERED GoogleAutoComplete to dom node with id: GoogleAutoComplete-react-component-f9a3e037-df00-4f35-9a7c-103c33b1208e with props, railsContext: Object {text: "google autocomplete"} Object {inMailer: false, i18nLocale: "en", i18nDefaultLocale: "en", href: "https://react-on-rails-basic-tutorial-mcl282.c9users.io/", location: "/"…}
  clientStartup.js?0ac5:149 Uncaught TypeError: ReactOnRails encountered an error while rendering component: GoogleAutoComplete.Original message: Cannot read property 'Autocomplete' of undefined
      at GoogleAutoComplete.initAutocomplete (eval at &lt;anonymous&gt; (webpack-bundle.self-cdcd22e….js?body=1:3586), &lt;anonymous&gt;:44:48)
      at GoogleAutoComplete.componentDidMount (eval at &lt;anonymous&gt; (webpack-bundle.self-cdcd22e….js?body=1:3586), &lt;anonymous&gt;:38:12)
      at eval (eval at &lt;anonymous&gt; (webpack-bundle.self-cdcd22e….js?body=1:2842), &lt;anonymous&gt;:265:25)
      at measureLifeCyclePerf (eval at &lt;anonymous&gt; (webpack-bundle.self-cdcd22e….js?body=1:2842), &lt;anonymous&gt;:75:12)
      at eval (eval at &lt;anonymous&gt; (webpack-bundle.self-cdcd22e….js?body=1:2842), &lt;anonymous&gt;:264:11)
      at CallbackQueue.notifyAll (eval at &lt;anonymous&gt; (webpack-bundle.self-cdcd22e….js?body=1:2296), &lt;anonymous&gt;:76:22)
      at ReactReconcileTransaction.close (eval at &lt;anonymous&gt; (webpack-bundle.self-cdcd22e….js?body=1:3004), &lt;anonymous&gt;:80:26)
      at ReactReconcileTransaction.closeAll (eval at &lt;anonymous&gt; (webpack-bundle.self-cdcd22e….js?body=1:2398), &lt;anonymous&gt;:206:25)
      at ReactReconcileTransaction.perform (eval at &lt;anonymous&gt; (webpack-bundle.self-cdcd22e….js?body=1:2398), &lt;anonymous&gt;:153:16)
      at batchedMountComponentIntoNode (eval at &lt;anonymous&gt; (webpack-bundle.self-cdcd22e….js?body=1:3130), &lt;anonymous&gt;:126:15)
  </code></pre>
  
  <p>Here is the relevant code:</p>
  
  <p>index.html.erb </p>
  
  <pre><code>&lt;html&gt;
    &lt;body&gt;
    &lt;%= react_component("GoogleAutoComplete") %&gt;
  
    &lt;script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?key=AIzaSyAnhYQqHo2V5AcFpcKKPX6rz0bVrw7xmZg&amp;libraries=places&amp;callback=initAutocomplete"
          &gt;&lt;/script&gt;
    &lt;/body&gt;
  &lt;/html&gt;
  </code></pre>
  
  <p>GoogleAutoComplete.jsx</p>
  
  <pre><code>import React, { PropTypes } from 'react';
  
  export default class GoogleAutoComplete extends React.Component {
    static propTypes = {
      }
    constructor(props) {
  
        super(props);
          this.state = { 
            autocomplete: {} 
          }
      }
  
      componentDidMount() {
        this.initAutocomplete();
      }
  
      initAutocomplete() {
        // eslint-disable-next-line no-undef
        const autocomplete = new google.maps.places.Autocomplete((this.refs.autoCompletePlaces), {types: ['geocode']});
  
        autocomplete.addListener('place_changed', this.fillInAddress);
        this.setState({ autocomplete });
      }
  
      geolocate() {
        if (navigator.geolocation) {
          navigator.geolocation.getCurrentPosition(function(position) {
            const geolocation = {
              lat: position.coords.latitude,
              lng: position.coords.longitude
            };
          });
        }
      }
  
      fillInAddress() {
        const componentForm = {
          street_number: 'short_name',
          route: 'long_name',
          locality: 'long_name',
          administrative_area_level_1: 'short_name',
          country: 'long_name',
          postal_code: 'short_name'
        };
      // Get the place details from the autocomplete object.
        const place = autocomplete.getPlace();
        for (let component in componentForm) {
          this.refs.component.value = '';
          this.refs.component.disabled = false;
        }
  
      // Get each component of the address from the place details
      // and fill the corresponding field on the form.
      for (let i = 0; i &lt; place.address_components.length; i++) {
        const addressType = place.address_components[i].types[0];
        if (componentForm[addressType]) {
          const val = place.address_components[i][componentForm[addressType]];
          this.refs.addressType.value = val;
        }
      }
    }
  
  
  
    render() {
      return (
        &lt;div&gt;
          &lt;div id="locationField"&gt;
            &lt;input 
              id="autocomplete" 
              placeholder="Enter your address"
              onFocus={this.geolocate}
              onChange={this.handleInputChange}
              ref="autoCompletePlaces"
            /&gt;
          &lt;/div&gt;
          &lt;table id="address"&gt;
            &lt;tbody&gt;
              &lt;tr&gt;
                &lt;td&gt;Street address&lt;/td&gt;
                &lt;td&gt;
                  &lt;input 
                    id="street_number"
                    disabled="true"/&gt;
                &lt;/td&gt;
                &lt;td&gt;
                  &lt;input 
                    id="route"
                    disabled="true"/&gt;
                &lt;/td&gt;
              &lt;/tr&gt;
              &lt;tr&gt;
                &lt;td&gt;City&lt;/td&gt;
                &lt;td&gt;
                  &lt;input 
                    id="locality"
                    disabled="true"/&gt;
                &lt;/td&gt;
              &lt;/tr&gt;
              &lt;tr&gt;
                &lt;td&gt;State&lt;/td&gt;
                &lt;td&gt;
                  &lt;input 
                    id="administrative_area_level_1" 
                    disabled="true"/&gt;
                  &lt;/td&gt;
                &lt;td&gt;Zip code&lt;/td&gt;
                &lt;td&gt;
                  &lt;input
                    id="postal_code"
                    disabled="true"/&gt;
                &lt;/td&gt;
              &lt;/tr&gt;
              &lt;tr&gt;
                &lt;td&gt;Country&lt;/td&gt;
                &lt;td&gt;
                  &lt;input
                    id="country" 
                    disabled="true"/&gt;
                &lt;/td&gt;
              &lt;/tr&gt;
            &lt;/tbody&gt;
          &lt;/table&gt;
        &lt;/div&gt;      
      );
    }
  }
  </code></pre>