最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Change agm-map google maps API Key dynamically in Angular 7 - Stack Overflow

programmeradmin0浏览0评论

I am building an app that lets you edit maps, the editor has google maps with the Agm map module, the end result for the user is an iframe with his map to embed into his webpage. I am using the module for the editor, and in the app.module.ts I import it with my API key.

import { AgmCoreModule } from '@agm/core';
...
imports: [
 ...
 AgmCoreModule.forRoot({
   apiKey: 'YOUR_KEY'
 })
]

The iframe will be a separate angular app that uses the same back-end. I would need the user's API key that will be fetched from the database but I can't get my head around on how can I build this part in Angular, it seems it creates the build with the api key, is it possible to do it in a way the key is modified on runtime? I've seen it done in jQuery. Where it can be fetched from the code in the script tag, or in vanilla js, an example:

<script async defer
    src=";callback=initMap">
</script>

In this last example it can be easily done, Thank you

I am building an app that lets you edit maps, the editor has google maps with the Agm map module, the end result for the user is an iframe with his map to embed into his webpage. I am using the module for the editor, and in the app.module.ts I import it with my API key.

import { AgmCoreModule } from '@agm/core';
...
imports: [
 ...
 AgmCoreModule.forRoot({
   apiKey: 'YOUR_KEY'
 })
]

The iframe will be a separate angular app that uses the same back-end. I would need the user's API key that will be fetched from the database but I can't get my head around on how can I build this part in Angular, it seems it creates the build with the api key, is it possible to do it in a way the key is modified on runtime? I've seen it done in jQuery. Where it can be fetched from the code in the script tag, or in vanilla js, an example:

<script async defer
    src="https://maps.googleapis./maps/api/js?key=YOUR_API_KEY&callback=initMap">
</script>

In this last example it can be easily done, Thank you

Share Improve this question asked Jun 1, 2020 at 22:03 Guillermo BascuñanaGuillermo Bascuñana 1622 silver badges14 bronze badges
Add a ment  | 

3 Answers 3

Reset to default 2

I did solve it straight away, in my case I got the key from the API with this code

import { AgmCoreModule, LAZY_MAPS_API_CONFIG, LazyMapsAPILoaderConfigLiteral } 
from '@agm/core';

export function agmConfigFactory(http: HttpClient, config: LazyMapsAPILoaderConfigLiteral) {
    const id = window.location.pathname.replace(/\//g, "");
    return () => http.get<any>(`${environment.baseUrl}/map-display/${id}`).pipe(
        map(response => {
            config.apiKey = response.key;
            return response;
        })
    ).toPromise();
}

The content of the api call and the id can be substituted with the desired key.

import { AgmCoreModule, LAZY_MAPS_API_CONFIG, LazyMapsAPILoaderConfigLiteral } 
from '@agm/core';

@Injectable()
export class GoogleMapsConfig implements LazyMapsAPILoaderConfigLiteral {
  apiKey: string = CONFIG.googleMapsAPIKey;
}


you must add a provider specifying the function to the providers array in @NgModule, in my case:

  providers: [
    {
        provide: APP_INITIALIZER,
        useFactory: agmConfigFactory,
        deps: [HttpClient, LAZY_MAPS_API_CONFIG],
        multi: true
    } 
  ],

You can useClass instead of useFactory for the generic example I showed. You still have to provide an initial key in the imports array of @NgModule, it can be a meaningless string

    AgmCoreModule.forRoot({ apiKey: "initialKey"}),

Adding to above answer, add the below to make the auto plete work

AgmCoreModule.forRoot({
  apiKey: 'initialKey',
  language: 'en',
  libraries: ['places']
}),

AppModule.ts file

import {APP_INITIALIZER} from '@angular/core';
import { LAZY_MAPS_API_CONFIG, LazyMapsAPILoaderConfigLiteral } from '@agm/core';
import { GoogleMapsInitializer } from './shared/services/googleMapsInitializer';

imports: [
  AgmCoreModule.forRoot({
    apiKey: '',// this should be empty
    libraries: ['places']
  })
],
  providers: [
    {
      // APP_INITIALIZER is the Angular dependency injection token.
      provide: APP_INITIALIZER,
      // Pass in the AGM dependency injection token.
      deps: [LAZY_MAPS_API_CONFIG, GoogleMapsInitializer],
      // Allow for multiple startup injectors if needed.
      multi: true,
      // UseFactory provides Angular with the function to invoke.
      useFactory: (config: LazyMapsAPILoaderConfigLiteral, initializer: GoogleMapsInitializer) => () => initializer.initialize(config),
    }]

GoogleMapsInitializer service

import { LazyMapsAPILoaderConfigLiteral } from '@agm/core';
import { GoogleMapsConfigService } from '../rest-services/googleMapsConfigService';

export class GoogleMapsInitializer {
  constructor(private googleMapsConfigService: GoogleMapsConfigService) { }

  async initialize(config: LazyMapsAPILoaderConfigLiteral): Promise<void> {
    try {
      const apiKey = await this.googleMapsConfigService.getGoogleMapsApiKey();
      console.log("API KEY IN INITIALIZE SERVICE ==> ", apiKey)
      config.apiKey = apiKey;
    } catch (error) {
      console.error('Error setting Google Maps API key:', error);
    }
  }
}

GoogleMapsConfigService service

import { HttpClient } from '@angular/mon/http';

export class GoogleMapsConfigService {
  constructor(private http: HttpClient) {}
  getGoogleMapsApiKey(): Promise<string> {
    const API_KEY_ENDPOINT = 'your api goes here';// get api key of google maps from backend service
    return this.http.post<any>(API_KEY_ENDPOINT, {}).toPromise()
      .then(response => response.apikey as string) // Replace 'apiKey' with the actual property name returned by your backend API.
      .catch(error => {
        console.error('Error fetching Google Maps API key:', error);
        return '';
      });
  }
}

During app startup, the APP_INITIALIZER in AppModule triggers the GoogleMapsInitializer service. The GoogleMapsInitializer service fetches the Google Maps API key using GoogleMapsConfigService. Once the key is obtained, it is dynamically set in the config object for AgmCoreModule.

发布评论

评论列表(0)

  1. 暂无评论