Compiler v2
Compiler v2

Reputation: 3605

Type Error of Geocoder undefined in Angular

My Geocoder in my Angular project is crashing because it is undefined. I tried this: Getting 'Uncaught TypeError: Cannot read property 'geocode' of undefined ' error

But it doesn't work if I initialize it first or assign it. Both do not work.

My code, error in the first line:

private geoCoder = new google.maps.Geocoder();

  @ViewChild('search', { static: false })
  public searchElementRef: ElementRef;

  constructor(private maps: MapsAPILoader, private ngZone: NgZone){ }

  ngOnInit() {
    // Load places autocomplete
    this.maps.load().then(() => {
      this.setCurrentLocation();

      let autocomplete = new google.place.Autocomplete(this.searchElementRef.nativeElement, {
        types: ["address"]
      });

      autocomplete.addListener("place_changed", () => {
        this.ngZone.run(() => {
          // Get the place result
          let place: google.maps.places.PlaceResult = autocomplete.getPlace();

          // Verify result
          if (place.geometry === undefined || place.geometry === null) {
            return;
          }

          // Set latitude, longitude & zoom
          this.userLat = place.geometry.location.lat();
          this.userLng = place.geometry.location.lng();
          this.zoom = 12;
        });
      });
    });
  }

  // Get Current Location Coordinates
  private setCurrentLocation() {
    if ('geolocation' in navigator) {
      navigator.geolocation.getCurrentPosition((position) => {
        this.userLat = position.coords.latitude;
        this.userLng = position.coords.longitude;
        this.zoom = 15;
      });
    }
  }

getaddress(latitude, longitude) {
    this.geoCoder.geocode({ "location": { lat: latitude, lng: longitude } }, (results, status) => {
      console.log(results);
      console.log(status);

      if (status === "Ok") {
        if (results[0]) {
          this.zoom = 12;
          this.address = results[0].formatted_address;
        } else {
          window.alert("No results found.");
        }
      } else {
        window.alert("Something went wrong, please try again.");
      }
    });
  }

From (scroll down to Add Location/Places Search bar):

https://www.freakyjolly.com/angular-7-6-add-google-maps-in-angular-2-plus-applications-using-angular-google-maps-module-agm-core-easily/

How do you prevent the crash? Thanks!

EDIT: Fixed: https://stackblitz.com/edit/angular-rhbjrx

Upvotes: 1

Views: 3380

Answers (3)

Compiler v2
Compiler v2

Reputation: 3605

You need to make sure you have the correct import statement and using the correct library.

As Geocoder is not defined in @agm, but it is defined in @types/googlemaps and you need to download it if you do not have it: npm install --save @types/googlemaps.

Use this import statement: import { } from 'googlemaps'; after you made this file, index.d.ts in your src folder or root one, and declared inside it this:

index.d.ts

declare module "googlemaps";

And make sure you put brackets with your Geocoder: Geocoder().

This should fix the problem, as it did for me.

See https://stackblitz.com/edit/angular-rhbjrx

Upvotes: 0

Vadim Gremyachev
Vadim Gremyachev

Reputation: 59338

The error occurs since the moment when Geocoder is getting initialized, Google Maps API is not yet loaded. In Angular Google Maps library MapsAPILoader service could be utilized to ensure Google Maps API is loaded and then initialize Geocoder:

this.mapsAPILoader.load().then(() => {
   this.geoCoder = new google.maps.Geocoder;  
});

Here is an example (adapted from the official Geocoding Service example) which demonstrates how to utilize Goolge Maps Geocoding Service with Angular Google Maps

export class AppComponent implements OnInit {
  center = {lat: -34.397, lng: 150.644};
  position= {lat: null, lng: null};
  zoom: number = 8;
  address: string;
  private geoCoder;


  constructor(
    private mapsAPILoader: MapsAPILoader,
    private ngZone: NgZone
  ) { }


  ngOnInit() {
    this.mapsAPILoader.load().then(() => {
       this.geoCoder = new google.maps.Geocoder;  
    });
  }


  geocodeAddress(addressInput) {
    const address = addressInput.value;
    this.geoCoder.geocode({'address': address}, (results, status) => {
          if (status === 'OK') {
            this.position = {
              "lat": results[0].geometry.location.lat(),
              "lng": results[0].geometry.location.lng()
            }
          } else {
            alert('Geocode was not successful for the following reason: ' + status);
          }
    });
  }

}

And here is a demo

Upvotes: 1

Maihan Nijat
Maihan Nijat

Reputation: 9344

Wait for the map loader and then assign the Geocoder() in the ngOnInit():

this.mapsAPILoader.load().then(() => {
      this.setCurrentLocation();
      this.geoCoder = new google.maps.Geocoder;
  .....
}

Make sure to install:

npm install @types/googlemaps --save-dev

Edit:

Import properly in module.ts:

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { AgmCoreModule } from '@agm/core';

import { AppComponent } from './app.component';

@NgModule({
  imports:      [ 
    AgmCoreModule.forRoot({
      apiKey: 'AIzaSyCnn-_D68N95BaSpYRYn1E3N_DHGs1vz0Y',
      libraries: ["places"]
    }),
    BrowserModule,
    FormsModule,
    ReactiveFormsModule
   ],
  declarations: [ AppComponent ],
  bootstrap:    [ AppComponent ]
})
export class AppModule { }

Upvotes: 2

Related Questions