Reputation: 3605
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):
How do you prevent the crash? Thanks!
EDIT: Fixed: https://stackblitz.com/edit/angular-rhbjrx
Upvotes: 1
Views: 3380
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
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
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