Getting started - How to use Google maps api with angular-cli
The agm project pointed by @Steve G. give a good starting point, but for some reason (like manage your own request policy) you may want to make your own typed wrapper.Here how I did it with Angular Cli :
First step :
npm i --save @types/googlemaps
Secondly add the types to your tsconfig.app.json
:
"types": ["googlemaps"]
Finally write your typescript :
//nothing to import here//Replace this by anything without an ID_KEYconst getScriptSrc = (callbackName) => { return `https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&callback=${callbackName}`;}export class GMapService { private map: google.maps.Map; private geocoder: google.maps.Geocoder; private scriptLoadingPromise: Promise<void>; constructor() { //Loading script this.loadScriptLoadingPromise(); //Loading other components this.onReady().then(() => { this.geocoder = new google.maps.Geocoder(); }); } onReady(): Promise<void> { return this.scriptLoadingPromise; } initMap(mapHtmlElement: HTMLElement, options: google.maps.MapOptions): Promise<google.maps.Map> { return this.onReady().then(() => { return this.map = new google.maps.Map(mapHtmlElement, options); }); } private loadScriptLoadingPromise() { const script = window.document.createElement('script'); script.type = 'text/javascript'; script.async = true; script.defer = true; const callbackName: string = 'UNIQUE_NAME_HERE'; script.src = getScriptSrc(callbackName); this.scriptLoadingPromise = new Promise<void>((resolve: Function, reject: Function) => { (<any>window)[callbackName] = () => { resolve(); }; script.onerror = (error: Event) => { reject(error); }; }); window.document.body.appendChild(script); } /** Exemple of wrapped to promise API */ geocode(address: string | google.maps.GeocoderRequest): Promise<google.maps.GeocoderResult[]> { return this.onReady().then(() => { this.geocoder.geocode(typeof address == "google.maps.GeocoderRequest" ? address: {address: address}, (results: google.maps.GeocoderResult[], status: google.maps.GeocoderStatus) => { if(status == google.maps.GeocoderStatus.OK) { return results; } else { throw new Error(status.toString()); } }); }); });}
And so your map component will look like this :
@Component({ selector: 'app-gmap-wrapper', template: '<div #map style="width:400px; height:300px">loading...</div>'})export class GMapWrapperComponent implements OnInit { @ViewChild('map') mapRef: ElementRef; constructor(private gmapService: GMapService) { } ngOnInit() { this.gmapService.initMap(this.mapRef.nativeElement, { center: {lat: 1234.1234, lng: 1234.1234}, scrollwheel: true, zoom: 8 }); }}
This code should be better without the namespace google.maps
in prefix of all types. Maybe any suggestion ?
I also had troubles with AGM in componets, then i tried nu-maps and also there I had troubles.
So I used plain google api javascript and I think its better:https://cloud.google.com/maps-platform/?hl=de
- simple
- good documented
- not dependent of some guys who do not merge the pull requests
- it works!