Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

angular2-google-maps autocomplete not working

I am trying to add autocomplete to my project with angular2-google-maps. I add AgmCoreModule.forRoot (with libraries: 'places') in my AppModule and then added the autocomplete code in my component. Still I get "Cannot read property 'Autocomplete' of undefined" error. I tried checking the value of global var google, and google.map does not contain 'places' field. I am relatively new to angular2, so would need some help to understand what I am missing. My code is in AppModule
import { AgmCoreModule } from 'angular2-google-maps/core';

@NgModule({
    bootstrap: [ App ],
    declarations: [
      App,
      ErrorComponent,
    ],
    imports: [ // import Angular's modules
    AgmCoreModule.forRoot({
            apiKey: '[API_KEY_REDACTED]',
            libraries: ["places"]
        }),
      BrowserModule,

        FormsModule,
      ReactiveFormsModule,
      HttpModule,
      TranslateModule.forRoot(),
      RouterModule.forRoot(ROUTES, { useHash: true })
    ],
    providers: [ // expose our Services and Providers into Angular's dependency injection
      ENV_PROVIDERS,
      APP_PROVIDERS,
    ]
})
export class AppModule {

In AppComponent:

import {MapsAPILoader} from 'angular2-google-maps/core';
import { NgZone          }   from    '@angular/core';
declare var google: any;
export class EventInfoTab {
    @ViewChild('gmap') gmap:any;
 constructor(
        private _loader: MapsAPILoader,
        private zone            :   NgZone,
 )
 ngAfterViewInit(): void {
        this._loader.load().then(() => {
        let address = document.getElementById("location");
        console.log("google", google);
            let autocomplete = new google.maps.places.Autocomplete(address, {});
            console.log ("autocomplete",autocomplete);
            google.maps.event.addListener(autocomplete, 'place_changed', () => {
       this.zone.run(() => { 
          console.log ("autocomplete place_changed",autocomplete);
          var place = autocomplete.getPlace();
          this.lat = place.geometry.location.lat();
          this.lng = place.geometry.location.lng();
          //alert(JSON.stringify(place));
          this.markers[0] ={
                           lat: this.lat,
                           lng: this.lng,
                           label: 'x',
                           draggable: false
                           };
              });                           

              });
            });....
like image 215
Pooja Srivastava Avatar asked Jan 05 '17 20:01

Pooja Srivastava


2 Answers

So, I was able to make it work. I was trying to include the map with autocomplete in a feature component, after routing from the main component. I removed the code

'AgmCoreModule.forRoot({
            apiKey: '[API_KEY_REDACTED]',
            libraries: ["places"]
        }),'

from app module.ts and added it in the feature's module.ts imports and it worked.

like image 181
Pooja Srivastava Avatar answered Oct 19 '22 01:10

Pooja Srivastava


Since Pooja got hers working, and I had already completed a working example of Angular2 + angular2-google-maps + Autocomplete for her, I thought I'd add the code here to help future developers looking for something similar.

import {
  Component,
  NgModule,
  OnInit,
  NgZone
} from '@angular/core';

import {
  BrowserModule
} from '@angular/platform-browser';

import {
  AgmCoreModule,
  MapsAPILoader
} from 'angular2-google-maps/core';

declare var google: any;

@Component({
  selector: 'my-app',
  styles: [`
    .sebm-google-map-container {
       height: 300px;
     }
  `],
  template: `
    <sebm-google-map 
      [latitude]="lat"
      [longitude]="lng"
      [zoom]="zoom"
      [disableDefaultUI]="false"
      [zoomControl]="true">

      <sebm-google-map-marker 
          *ngFor="let m of markers; let i = index"
          (markerClick)="clickedMarker(m.label, i)"
          [latitude]="m.lat"
          [longitude]="m.lng"
          [label]="m.label"
          [markerDraggable]="m.draggable"
          (dragEnd)="markerDragEnd(m, $event)">

        <sebm-google-map-info-window>
          <strong>InfoWindow content</strong>
        </sebm-google-map-info-window>

      </sebm-google-map-marker>

    </sebm-google-map>
    <input type="text" id="autocompleteInput">
`})
export class App implements OnInit {

  constructor(
    private _loader: MapsAPILoader,
    private _zone: NgZone) {
  }

  ngOnInit(): void {
    this.autocomplete();
  }

  autocomplete() {
    this._loader.load().then(() => {
        var autocomplete = new google.maps.places.Autocomplete(document.getElementById("autocompleteInput"), {});
        google.maps.event.addListener(autocomplete, 'place_changed', () => {
            this._zone.run(() => {
              var place = autocomplete.getPlace();

              this.markers.push({
                lat: place.geometry.location.lat(),
                  lng: place.geometry.location.lng(),
                  label: place.name,
              });

              this.lat = place.geometry.location.lat();
              this.lng = place.geometry.location.lng();

              console.log(place);
            });
        });
    });
  }

  // google maps zoom level
  zoom: number = 8;

  // initial center position for the map
  lat: number = 51.673858;
  lng: number = 7.815982;

  clickedMarker(label: string, index: number) {
    console.log(`clicked the marker: ${label || index}`)
  }

  mapClicked($event: MouseEvent) {
    this.markers.push({
      lat: $event.coords.lat,
      lng: $event.coords.lng
    });
  }

  markerDragEnd(m: marker, $event: MouseEvent) {
    console.log('dragEnd', m, $event);
  }

  markers: marker[] = [];
}
// just an interface for type safety.
interface marker {
    lat: number;
    lng: number;
    label?: string;
    draggable: boolean;
}

@NgModule({
  imports: [ 
    BrowserModule, 
    AgmCoreModule.forRoot({
        libraries: ['places']
    }) 
  ],
  declarations: [ App ],
  bootstrap: [ App ]
})
export class AppModule {}

Working Plnkr

4/17/2017 UPDATE

In version 1.0.0-beta.0 - green-zebra, the AGM team released a breaking change with the naming of their components which will require an update to your template file as follows:

<agm-map
    [latitude]="lat"
    [longitude]="lng"
    [zoom]="zoom"
    [disableDefaultUI]="false"
    [zoomControl]="true">

    <agm-marker
        *ngFor="let m of markers; let i = index"
        (markerClick)="clickedMarker(m.label, i)"
        [latitude]="m.lat"
        [longitude]="m.lng"
        [label]="m.label"
        [markerDraggable]="m.draggable"
        (dragEnd)="markerDragEnd(m, $event)">

    <agm-info-window>
        <strong>InfoWindow content</strong>
    </agm-info-window>

    </agm-marker>

</agm-map>
<input type="text" id="autocompleteInput">

An updated version of the above plnkr/code can be found in the following GitHub repo.

like image 38
Steve Gomez Avatar answered Oct 19 '22 01:10

Steve Gomez