Angular-google-maps: como inicializar o módulo com a variável apiKey

Criado em 3 fev. 2017  ·  12Comentários  ·  Fonte: SebastianM/angular-google-maps

Eu tenho a chave API do google em um serviço de configuração singleton (uma maneira de compartilhar a configuração do aplicativo em todo o aplicativo).

Como posso passar a variável apiKey para o módulo dentro do @NgModule?

`@NgModule ({

importações: [
BrowserModule,
CommonModule,
FormsModule,
AgmCoreModule.forRoot ({
apiKey: 'YOUR_KEY' // <- Não consigo usar uma constante !!! Como posso passar uma variável?
})
],
provedores: [],
declarações: [AppComponent],
bootstrap: [AppComponent]
}) `

stale discussion / question

Comentários muito úteis

Depende do tipo de ferramenta de construção que você está usando (por exemplo, angular-cli ou webpack personalizado ou ...) e de onde a variável deve vir.
Isso pode ser um pouco complicado. Especialmente quando você também deseja usar a compilação AOT, o que evita muito código dinâmico dentro de @NgModule .

A solução que implementei atualmente está substituindo o 'provedor de configuração preguiçoso' em meu app.module principal.

No módulo em que realmente uso o mapa, uso uma configuração vazia no forRoot:

AgmCoreModule.forRoot()

Em meu app.module.ts:
importe o token de injeção:

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

Adicione aos provedores em @NgModule :

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

E implemente essa classe 'GoogleMapsConfig', que deve implementar a interface LazyMapsAPILoaderConfigLiteral (de 'from' angular2-google-maps / core / services ').

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

Nesse injetável posso injetar outros serviços e ler a configuração de algum lugar.
(por exemplo, se você usar angular-cli, você pode importar ambientes para lá). Ou talvez leia o domínio no navegador ... ou chame uma API do lado do servidor ...

Todos 12 comentários

Depende do tipo de ferramenta de construção que você está usando (por exemplo, angular-cli ou webpack personalizado ou ...) e de onde a variável deve vir.
Isso pode ser um pouco complicado. Especialmente quando você também deseja usar a compilação AOT, o que evita muito código dinâmico dentro de @NgModule .

A solução que implementei atualmente está substituindo o 'provedor de configuração preguiçoso' em meu app.module principal.

No módulo em que realmente uso o mapa, uso uma configuração vazia no forRoot:

AgmCoreModule.forRoot()

Em meu app.module.ts:
importe o token de injeção:

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

Adicione aos provedores em @NgModule :

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

E implemente essa classe 'GoogleMapsConfig', que deve implementar a interface LazyMapsAPILoaderConfigLiteral (de 'from' angular2-google-maps / core / services ').

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

Nesse injetável posso injetar outros serviços e ler a configuração de algum lugar.
(por exemplo, se você usar angular-cli, você pode importar ambientes para lá). Ou talvez leia o domínio no navegador ... ou chame uma API do lado do servidor ...

Eu apenas tentei o acima. Ele consegue contornar erros de AoT, mas a chave de API não está sendo passada para o Google Maps - então ele retorna o erro de chave ausente.

No meu caso de uso, estou usando o extended-define-webpack-plugin para adicionar configurações globais de configuração em tempo de compilação (chaves de API que podem ser alteradas com base no tipo de compilação, 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 {}

E, no meu módulo de carregamento lento, onde estou usando o mapa, chamando AgmCoreModule.forRoot()

Estou usando angular 4 e CLI 1.0.2, estou tentando obter o código acima por @kyranjamie, mas não consigo fazer isso funcionar, o que estamos tentando é basicamente o mesmo - configurar uma chave diferente para prod vs. dev

este é o meu código, o que estou fazendo de errado?

`
@Injectable ()
export class GoogleMapsConfig implementa LazyMapsAPILoaderConfigLiteral {
public apiKey: string;
construtor () {
if (ambiente.produção) {
this.apiKey = CHAVE INSERIDA AQUI
};
}
}
@NgModule ({
declarações: [
AppComponent
],
importações: [
BrowserModule,
FormsModule,
ReactiveFormsModule,
HttpModule,
AppRoutingModule,
NgbModule.forRoot (),
NouisliderModule,
AgmCoreModule.forRoot ()
],
provedores: [
{fornecer: LAZY_MAPS_API_CONFIG, useClass: GoogleMapsConfig}
],
bootstrap: [AppComponent]
})
export class AppModule {

}
`

Tem certeza de que if (environment.production) algum dia se tornará verdadeiro?

Resolvi isso, obrigado pelo seu feedback

@daBishMan ou @kyranjamie , se vocês algum dia descobriram isso, poderiam postar sua solução final? @kyranjamie , meu problema parece ser semelhante ao seu, ... em uma construção de produto no que diz respeito ao AOT, inicialização agm-map na solicitação para maps.google.com, ... nenhum parâmetro URL API-KEY está sendo enviado . Portanto, ele retorna com erros de "chave de API ausente".

@ jorrit-wehelp, obrigado por sua orientação. Estou incluindo abaixo o que está funcionando para mim ....

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)
  }
}

no meu @ngmodule principal, tenho isso em provedores ...

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

A referência à classe Config é uma variável webpack em tempo de construção que substitui as configurações de um mapa de variáveis ​​usado nos modos Dev ou Prod.

Olá

Consegui obter a chave dinâmica, como por comentários de @jorrit-wehelp, mas no meu cenário, após o logout do usuário e logado, o valor agmKey não está atualizando e não é capaz de ver o mapa

o que eu fiz foi como em nosso componente de módulo, adicionamos o seguinte código
Então movi class GoogleMapsConfig e {provide: LAZY_MAPS_API_CONFIG, useClass: GoogleMapsConfig} dentro do mapa @component

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

@Injectable ();
class GoogleMapsConfig implementa LazyMapsAPILoaderConfigLiteral {
public apiKey: string;
construtor () {
console.log ('MAPAS DENTRO'); // Isso não é exibido no console
this.apiKey = _authService.currentUser () && _authService.currentUser (). agmKey? _authService.currentUser (). agmKey: '';
_authService.getMapKey $ .subscribe ((key) => {
this.apiKey = chave;
})
}
}

@Componente({
seletor: 'map-comp',
templateUrl: './dyn-map.component.html',
styleUrls: ['./dyn-map.component.scss'],
provedores: [{fornecer: LAZY_MAPS_API_CONFIG, useClass: GoogleMapsConfig}],
encapsulamento: ViewEncapsulation.None
})

`` `
depois que sairmos e fizermos login com outro usuário, o controle não virá para dentro da classe GoogleMapsConfig. O que posso fazer para resolver esse problema ??

Eu tinha a solução de @jorrit-wehelp funcionando, mas apenas intermitentemente porque eu tinha uma condição de corrida em que meu serviço que retorna a chave de API nem sempre a retornava a tempo para oelemento para tentar renderizar. A fim de forçarpara esperar até que a chave api fosse devolvida, simplesmente fiz o seguinte:

construtor do meu 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);
    });
  }

Em seguida, na marcação:

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

Não sei se isso se aplica a todos ou se é mais caso a caso, mas descobri que isso é o resultado do processo de compilação AOT do Angular, ao contrário de um problema com o próprio agm. Aqui está uma visão geral da situação que tive.

Eu queria fazer com que a configuração da chave de API fosse conduzida em vez de uma string codificada, de forma que a passagem por ambientes diferentes me permitisse usar chaves de API diferentes e monitorar o uso da API. Para fazer isso, fiz meu back-end .NET injetar um pouco de JavaScript com o valor de que eu precisava no namespace global, armazenado em Example.Namespace.GoogleMapsApiKey . Com isso em mente, aqui estava meu 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 {}

Pensei que a criação de uma definição de tipo para alguma variável global const com o valor de que eu precisava seria incluída durante o processo de construção AOT. No entanto, o compilador AOT oferece suporte apenas a Somente variáveis ​​e constantes inicializadas " sem um erro sendo emitido da CLI Angular. Uma vez que mudei para usar algum tipo de provedor LAZY_MAPS_API_CONFIG usando uma classe, consegui usar com sucesso.

Este problema foi marcado automaticamente como obsoleto porque não teve atividades recentes. Ele será fechado se nenhuma outra atividade ocorrer. Obrigado por suas contribuições.

Esta página foi útil?
0 / 5 - 0 avaliações

Questões relacionadas

ChrisDevinePimss picture ChrisDevinePimss  ·  3Comentários

Subhojit1992 picture Subhojit1992  ·  3Comentários

nthonymiller picture nthonymiller  ·  4Comentários

ostapch picture ostapch  ·  4Comentários

maneesht picture maneesht  ·  3Comentários