Angular-google-maps: cómo iniciar el módulo con la variable apiKey

Creado en 3 feb. 2017  ·  12Comentarios  ·  Fuente: SebastianM/angular-google-maps

Tengo la clave de la API de Google en un servicio de configuración de singleton (una forma de compartir la configuración de la aplicación en toda la aplicación).

¿Cómo puedo pasar la variable apiKey al módulo dentro de @NgModule?

`@NgModule ({

importaciones: [
BrowserModule,
CommonModule,
FormsModule,
AgmCoreModule.forRoot ({
apiKey: 'YOUR_KEY' // <- ¡¡¡No puedo usar una constante !!! ¿Cómo puedo pasar una variable?
})
],
proveedores: [],
declaraciones: [AppComponent],
bootstrap: [AppComponent]
}) `

stale discussion / question

Comentario más útil

Depende del tipo de herramienta de compilación que esté utilizando (por ejemplo, angular-cli o paquete web personalizado o ...) y de dónde debería provenir la variable.
Esto puede resultar un poco complicado. Especialmente cuando también desea utilizar la compilación AOT, que evita demasiado código dinámico dentro de @NgModule .

La solución que implementé actualmente está anulando el 'proveedor de configuración perezoso' en mi módulo de aplicación principal.

En el módulo donde realmente uso el mapa, uso una configuración vacía en forRoot:

AgmCoreModule.forRoot()

En mi app.module.ts:
importar el token de inyección:

import { LAZY_MAPS_API_CONFIG }
  from 'angular2-google-maps/core/services';

Agregar a proveedores en @NgModule :

providers: [
    {provide: LAZY_MAPS_API_CONFIG, useClass: GoogleMapsConfig}
  ],

E implemente esa clase 'GoogleMapsConfig', que debería implementar la interfaz LazyMapsAPILoaderConfigLiteral (desde 'desde' angular2-google-maps / core / services ').

@Injectable()
class GoogleMapsConfig {
  apiKey: string;
...
  constructor() {
    apiKey = getMyApiKeyFromSomewhere()
...
  }
}

En ese inyectable puedo inyectar otros servicios y leer la configuración desde algún lugar.
(por ejemplo, si usa angular-cli, puede importar entornos allí). O tal vez lea el dominio desde el navegador ... o llame a una API del lado del servidor ...

Todos 12 comentarios

Depende del tipo de herramienta de compilación que esté utilizando (por ejemplo, angular-cli o paquete web personalizado o ...) y de dónde debería provenir la variable.
Esto puede resultar un poco complicado. Especialmente cuando también desea utilizar la compilación AOT, que evita demasiado código dinámico dentro de @NgModule .

La solución que implementé actualmente está anulando el 'proveedor de configuración perezoso' en mi módulo de aplicación principal.

En el módulo donde realmente uso el mapa, uso una configuración vacía en forRoot:

AgmCoreModule.forRoot()

En mi app.module.ts:
importar el token de inyección:

import { LAZY_MAPS_API_CONFIG }
  from 'angular2-google-maps/core/services';

Agregar a proveedores en @NgModule :

providers: [
    {provide: LAZY_MAPS_API_CONFIG, useClass: GoogleMapsConfig}
  ],

E implemente esa clase 'GoogleMapsConfig', que debería implementar la interfaz LazyMapsAPILoaderConfigLiteral (desde 'desde' angular2-google-maps / core / services ').

@Injectable()
class GoogleMapsConfig {
  apiKey: string;
...
  constructor() {
    apiKey = getMyApiKeyFromSomewhere()
...
  }
}

En ese inyectable puedo inyectar otros servicios y leer la configuración desde algún lugar.
(por ejemplo, si usa angular-cli, puede importar entornos allí). O tal vez lea el dominio desde el navegador ... o llame a una API del lado del servidor ...

Intenté lo anterior. Se las arregla para eludir los errores de AoT, pero la clave API no se pasa a Google Maps, por lo que devuelve un error de falta de clave.

En mi caso de uso, estoy usando el extendido-define-webpack-plugin para agregar una configuración de configuración global en tiempo de compilación (claves de API que pueden cambiar según el tipo de compilación, etc.).

import { LAZY_MAPS_API_CONFIG, LazyMapsAPILoaderConfigLiteral } from 'angular2-google-maps/core/services';

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

@NgModule({
  declarations: [...],
  imports: [...],
  providers: [{provide: LAZY_MAPS_API_CONFIG, useClass: GoogleMapsConfig}],
  bootstrap: [AppComponent]
})
export class AppModule {}

Y, en mi módulo de carga diferida donde estoy usando el mapa, llamo AgmCoreModule.forRoot()

Estoy usando angular 4 y CLI 1.0.2, estoy tratando de obtener el código anterior por @kyranjamie pero no puedo hacer que esto funcione, lo que estamos intentando es básicamente la misma configuración de una clave diferente para prod vs dev

este es mi código, ¿qué estoy haciendo mal?

'
@Inyectable ()
export class GoogleMapsConfig implementa LazyMapsAPILoaderConfigLiteral {
apiKey pública: cadena;
constructor () {
if (environment.production) {
this.apiKey = CLAVE INSERTADA AQUÍ
};
}
}
@NgModule ({
declaraciones: [
AppComponent
],
importaciones: [
BrowserModule,
FormsModule,
ReactiveFormsModule,
HttpModule,
AppRoutingModule,
NgbModule.forRoot (),
NouisliderModule,
AgmCoreModule.forRoot ()
],
proveedores: [
{proporcionar: LAZY_MAPS_API_CONFIG, useClass: GoogleMapsConfig}
],
bootstrap: [AppComponent]
})
export class AppModule {

}
'

¿Estás seguro de que if (environment.production) alguna vez se resolverá como verdadero?

He resuelto esto gracias por tus comentarios.

@daBishMan o @kyranjamie , si alguna vez se @kyranjamie , mi problema parece ser similar al tuyo, ... en una compilación de producto en lo que respecta a AOT, inicialización de agm-map en la solicitud a maps.google.com, ... no se envía ningún parámetro URL API-KEY . Por lo tanto, vuelve con errores de "clave api faltante".

@ jorrit-wehelp, gracias por su orientación. Estoy incluyendo a continuación lo que me está funcionando ...

import {Injectable} from "@angular/core";
import {LazyMapsAPILoaderConfigLiteral} from "@agm/core";
import {Config} from "../providers/config";

@Injectable()
export class MapsConfig implements LazyMapsAPILoaderConfigLiteral{
  public apiKey: string
  public libraries: string[]
  constructor(config: Config) {
    this.apiKey = config.get("MAP_API_JS_KEY")
    this.libraries = ['places']
    console.log("lazy map init with " + this.apiKey)
  }
}

en mi @ngmodule principal, tengo esto en los proveedores ...

    {
      provide: LAZY_MAPS_API_CONFIG,
      useClass: MapsConfig,
      deps: [Config]
    }

La referencia a la clase Config es una variable de paquete web en tiempo de compilación que reemplaza las configuraciones de un mapa de variables utilizadas en los modos Dev o Prod.

Hola

Pude lograr la clave dinámica, como en los comentarios de @ jorrit-wehelp, pero en mi escenario, después de que el usuario cerró la sesión e inició sesión, el valor de agmKey no se actualiza y no puede ver el mapa

lo que hice fue como en nuestro componente de módulo agregamos el siguiente código
Así que moví class GoogleMapsConfig y {provide: LAZY_MAPS_API_CONFIG, useClass: GoogleMapsConfig} dentro del mapa @component

`` ...
importar {LAZY_MAPS_API_CONFIG, LazyMapsAPILoaderConfigLiteral} desde '@ agm / core';
importar {AuthService} desde '@ pl-core / _services';

@Inyectable ();
class GoogleMapsConfig implementa LazyMapsAPILoaderConfigLiteral {
apiKey pública: cadena;
constructor () {
console.log ('MAPAS INTERNOS'); // Esto no se muestra en la consola
this.apiKey = _authService.currentUser () && _authService.currentUser (). agmKey? _authService.currentUser (). agmKey: '';
_authService.getMapKey $ .subscribe ((clave) => {
this.apiKey = clave;
})
}
}

@Componente({
selector: 'map-comp',
templateUrl: './dyn-map.component.html',
styleUrls: ['./dyn-map.component.scss'],
proveedores: [{proporcionar: LAZY_MAPS_API_CONFIG, useClass: GoogleMapsConfig}],
encapsulación: ViewEncapsulation.None
})

''
después de cerrar la sesión e iniciar sesión con otro usuario, el control no entra en la clase GoogleMapsConfig, ¿qué puedo hacer para resolver este problema?

Tenía la solución de @ jorrit-wehelp funcionando, pero solo de forma intermitente porque tenía una condición de carrera en la que mi servicio que devuelve la clave api no siempre la devuelve a tiempo para elelemento para intentar renderizar. Para forzarpara esperar hasta que se devolviera la clave de la API, simplemente hice esto:

constructor de mi componente de mapa:

constructor(private envService: EnvironmentService) {
    this.envService.environment$.subscribe(environment => {
      // setTimeout is to wait a beat since my GoogleMapsConfig receives
      // the key at the same instant.
      setTimeout(() => this.gmapsApiKeyReady = true);
    });
  }

Luego, en el marcado:

<agm-map *ngIf="gmapsApiKeyReady" ...></agm-map>

No sé si esto se aplicará a todos o si se trata más de un caso por caso, pero descubrí que esto es el resultado del proceso de compilación AOT de Angular, en lugar de un problema con agm en sí. Aquí hay una descripción general de la situación que tuve.

Quería hacer que la configuración de la clave de API fuera impulsada en lugar de una cadena codificada, de modo que moverme a través de diferentes entornos me permitiera usar diferentes claves de API y monitorear el uso de la API. Para hacer esto, hice que mi back-end .NET inyectara algo de JavaScript con el valor que necesitaba en el espacio de nombres global, almacenado en Example.Namespace.GoogleMapsApiKey . Con eso en mente, aquí estaba mi código TypeScript.

// typings.d.ts
declare namespace Example.Namespace {
    export const GoogleMapsApiKey: string;
}

// app.module.ts
import { AgmCoreModule } from "@agm/core";
import { NgModule } from "@angular/core";

@NgModule({
    // ...
    imports: [
        AgmCoreModule.forRoot({
            apiKey: Example.Namespace.GoogleMapsApiKey,
        })
    ],
    // ...
})
export class AppModule {}

Pensé que crear una definición de tipo para alguna variable global constante con el valor que necesitaba se incluiría durante el proceso de compilación de AOT. Sin embargo, resulta que el compilador AOT solo admite un subconjunto de herramientas de TypeScript , lo que impidió que la variable se incluyera en el momento de la compilación. Efectivamente, lo que estaba sucediendo era un error de " Solo variables y constantes inicializadas " sin que se emitiera un error desde la CLI de Angular. Una vez que hice el cambio para usar algún tipo de proveedor LAZY_MAPS_API_CONFIG usando una clase que pude con éxito.

Este problema se ha marcado automáticamente como obsoleto porque no ha tenido actividad reciente. Se cerrará si no se produce más actividad. Gracias por sus aportaciones.

¿Fue útil esta página
0 / 5 - 0 calificaciones

Temas relacionados

Halynsky picture Halynsky  ·  3Comentarios

n1t3w0lf picture n1t3w0lf  ·  3Comentarios

alexweber picture alexweber  ·  4Comentarios

stot3 picture stot3  ·  3Comentarios

gnujeremie picture gnujeremie  ·  3Comentarios