Reputation: 43
Im using sebastine google map in angular 2 application. I know AgmCoreModule.forRoot({ apiKey: "xxxxxxxx" }) can be used to set API key but I need to set API key from a angular service in my @component is it possible....help needed.
Upvotes: 4
Views: 4797
Reputation: 3819
you have put the API key in the app.module.ts
under the @NgModule
and make sure to enable Maps JavaScript API in the google cloud console
https://console.cloud.google.com/apis/library/maps-backend.googleapis.com
Thanks!
@NgModule({
imports: [
BrowserModule,
FormsModule,
AgmCoreModule.forRoot({
// please get your own API key here:
// https://developers.google.com/maps/documentation/javascript/get-api-key?hl=en
apiKey: 'API_KEY'
})
],
declarations: [ AppComponent, HelloComponent ],
bootstrap: [ AppComponent ]
})
export class AppModule { }
Upvotes: 0
Reputation: 11
I added an resolver to get the API key
import { Resolve, ActivatedRouteSnapshot } from '@angular/router'
import { Injectable, Inject } from '@angular/core'
import { SomeService } from '../services/some.service'
import { LazyMapsAPILoaderConfigLiteral, LAZY_MAPS_API_CONFIG } from '@agm/core'
import { Observable, of } from 'rxjs'
import { map, catchError } from 'rxjs/operators'
@Injectable()
export class GoogleMapAPiResolver implements Resolve<boolean> {
constructor(
private someService: SomeService,
@Inject(LAZY_MAPS_API_CONFIG)
private config: LazyMapsAPILoaderConfigLiteral
) {}
resolve(router: ActivatedRouteSnapshot): Observable<boolean> {
return this.someService.getGoogleMapApiKey().pipe(
catchError(error => {
return of(false)
}),
map(response => {
this.config.apiKey = response
return true
})
)
}
}
The SomeService consume an endpoint that return the Key
Upvotes: 0
Reputation: 613
You may need to update provide a custom provider like this { provide: MapsAPILoader, useClass: CustomLazyAPIKeyLoader }
where you have imported AgmCoreModule
.
And in CustomLazyAPIKeyLoader
class override the load method.
import { Injectable, Inject } from '@angular/core';
import { Http, Response, Headers, RequestOptions } from '@angular/http';
import { MapsAPILoader, LAZY_MAPS_API_CONFIG, LazyMapsAPILoaderConfigLiteral, GoogleMapsScriptProtocol } from 'angular2-google-maps/core';
import { DocumentRef, WindowRef } from 'angular2-google-maps/core/utils/browser-globals';
@Injectable()
export class CustomLazyAPIKeyLoader extends MapsAPILoader {
private _scriptLoadingPromise: Promise<void>;
private _config: LazyMapsAPILoaderConfigLiteral;
private _windowRef: WindowRef;
private _documentRef: DocumentRef;
constructor( @Inject(LAZY_MAPS_API_CONFIG) config: any, w: WindowRef, d: DocumentRef, private http: Http) {
super();
this._config = config || {};
this._windowRef = w;
this._documentRef = d;
}
load(): Promise<void> {
if (this._scriptLoadingPromise) {
return this._scriptLoadingPromise;
}
const script = this._documentRef.getNativeDocument().createElement('script');
script.type = 'text/javascript';
script.async = true;
script.defer = true;
const callbackName: string = `angular2GoogleMapsLazyMapsAPILoader`;
this.http.get("getKey")
.subscribe((res: any) => {
this._config.apiKey = res._body;
script.src = this._getScriptSrc(callbackName);
this._documentRef.getNativeDocument().body.appendChild(script);
});
this._scriptLoadingPromise = new Promise<void>((resolve: Function, reject: Function) => {
(<any>this._windowRef.getNativeWindow())[callbackName] = () => { console.log("loaded"); resolve(); };
script.onerror = (error: Event) => { reject(error); };
});
return this._scriptLoadingPromise;
}
private _getScriptSrc(callbackName: string): string {
let protocolType: GoogleMapsScriptProtocol =
(this._config && this._config.protocol) || GoogleMapsScriptProtocol.HTTPS;
let protocol: string;
switch (protocolType) {
case GoogleMapsScriptProtocol.AUTO:
protocol = '';
break;
case GoogleMapsScriptProtocol.HTTP:
protocol = 'http:';
break;
case GoogleMapsScriptProtocol.HTTPS:
protocol = 'https:';
break;
}
const hostAndPath: string = this._config.hostAndPath || 'maps.googleapis.com/maps/api/js';
const queryParams: { [key: string]: string | Array<string> } = {
v: this._config.apiVersion || '3',
callback: callbackName,
key: this._config.apiKey,
client: this._config.clientId,
channel: this._config.channel,
libraries: this._config.libraries,
region: this._config.region,
language: this._config.language
};
const params: string =
Object.keys(queryParams)
.filter((k: string) => queryParams[k] != null)
.filter((k: string) => {
// remove empty arrays
return !Array.isArray(queryParams[k]) ||
(Array.isArray(queryParams[k]) && queryParams[k].length > 0);
})
.map((k: string) => {
// join arrays as comma seperated strings
let i = queryParams[k];
if (Array.isArray(i)) {
return { key: k, value: i.join(',') };
}
return { key: k, value: queryParams[k] };
})
.map((entry: { key: string, value: string }) => { return `${entry.key}=${entry.value}`; })
.join('&');
return `${protocol}//${hostAndPath}?${params}`;
}
}
this.http.get("getKey")
.subscribe((res: any) => {
this._config.apiKey = res._body;
script.src = this._getScriptSrc(callbackName);
this._documentRef.getNativeDocument().body.appendChild(script);
});
Above code will make it async.
Upvotes: 2