Angular-google-maps: comment initialiser le module avec la variable apiKey

Créé le 3 févr. 2017  ·  12Commentaires  ·  Source: SebastianM/angular-google-maps

J'ai la clé google api dans un service de configuration singleton (un moyen de partager la configuration de l'application sur toute l'application).

Comment puis-je transmettre la variable apiKey au module dans @NgModule?

`@NgModule ({

importations: [
NavigateurModule,
CommonModule,
FormulairesModule,
AgmCoreModule.forRoot ({
apiKey: 'YOUR_KEY' // <- Je ne peux pas utiliser de constante !!! Comment puis-je passer une variable?
})
],
fournisseurs: [],
déclarations: [AppComponent],
bootstrap: [AppComponent]
}) `

stale discussion / question

Commentaire le plus utile

Cela dépend du type d'outil de construction que vous utilisez (par exemple angular-cli ou webpack personnalisé ou ...) et d'où la variable doit provenir.
Cela peut être un peu délicat. Surtout lorsque vous souhaitez également utiliser la compilation AOT, ce qui empêche trop de code dynamique à l'intérieur du @NgModule .

La solution que j'ai actuellement implémentée remplace le `` fournisseur de configuration paresseux '' dans mon app.module principal.

Dans le module où j'utilise réellement la carte, j'utilise une configuration vide dans le forRoot:

AgmCoreModule.forRoot()

Dans mon app.module.ts:
importez le jeton d'injection:

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

Ajouter aux fournisseurs en @NgModule :

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

Et implémentez cette classe 'GoogleMapsConfig', qui devrait implémenter l'interface LazyMapsAPILoaderConfigLiteral (de 'from' angular2-google-maps / core / services ').

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

Dans cet injectable, je peux injecter d'autres services et lire la configuration de quelque part.
(par exemple, si vous utilisez angular-cli, vous pouvez y importer des environnements). Ou peut-être lire le domaine à partir du navigateur ... ou appeler une API côté serveur ...

Tous les 12 commentaires

Cela dépend du type d'outil de construction que vous utilisez (par exemple angular-cli ou webpack personnalisé ou ...) et d'où la variable doit provenir.
Cela peut être un peu délicat. Surtout lorsque vous souhaitez également utiliser la compilation AOT, ce qui empêche trop de code dynamique à l'intérieur du @NgModule .

La solution que j'ai actuellement implémentée remplace le `` fournisseur de configuration paresseux '' dans mon app.module principal.

Dans le module où j'utilise réellement la carte, j'utilise une configuration vide dans le forRoot:

AgmCoreModule.forRoot()

Dans mon app.module.ts:
importez le jeton d'injection:

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

Ajouter aux fournisseurs en @NgModule :

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

Et implémentez cette classe 'GoogleMapsConfig', qui devrait implémenter l'interface LazyMapsAPILoaderConfigLiteral (de 'from' angular2-google-maps / core / services ').

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

Dans cet injectable, je peux injecter d'autres services et lire la configuration de quelque part.
(par exemple, si vous utilisez angular-cli, vous pouvez y importer des environnements). Ou peut-être lire le domaine à partir du navigateur ... ou appeler une API côté serveur ...

J'ai juste essayé ce qui précède. Il parvient à contourner les erreurs AoT, mais la clé API n'est pas transmise à Google Maps - elle renvoie donc une erreur de clé manquante.

Dans mon cas d'utilisation, j'utilise l' extension-define-webpack-plugin pour ajouter des paramètres de configuration globaux au moment de la compilation (clés API qui peuvent changer en fonction du type de construction, 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 {}

Et, dans mon module chargé paresseusement où j'utilise la carte, j'appelle AgmCoreModule.forRoot()

J'utilise angular 4 et CLI 1.0.2, j'essaie d'obtenir le code ci-dessus par @kyranjamie mais je ne peux pas faire fonctionner cela, ce que nous essayons est fondamentalement la même configuration d'une clé différente pour prod vs dev

c'est mon code, qu'est-ce que je fais de mal?

''
@Injectable ()
la classe d'exportation GoogleMapsConfig implémente LazyMapsAPILoaderConfigLiteral {
public apiKey: chaîne;
constructeur () {
if (environnement.production) {
this.apiKey = CLÉ INSÉRÉE ICI
};
}
}
@NgModule ({
déclarations: [
AppComponent
],
importations: [
NavigateurModule,
FormulairesModule,
ReactiveFormsModule,
HttpModule,
AppRoutingModule,
NgbModule.forRoot (),
NouisliderModule,
AgmCoreModule.forRoot ()
],
fournisseurs: [
{fournir: LAZY_MAPS_API_CONFIG, useClass: GoogleMapsConfig}
],
bootstrap: [AppComponent]
})
classe d'exportation AppModule {

}
''

Êtes-vous sûr que if (environment.production) se résoudra jamais à vrai?

J'ai résolu ce problème merci pour vos commentaires

@daBishMan ou @kyranjamie , si vous avez déjà compris cela, pourriez-vous publier votre solution finale? @kyranjamie , mon problème semble être similaire au vôtre, ... sur une version de produit où AOT est concerné, initialisation agm-map dans la demande à maps.google.com, ... aucun paramètre d'URL API-KEY n'est envoyé . Par conséquent, il revient avec des erreurs "clé API manquante".

@ jorrit-wehelp, merci pour vos conseils. J'inclus ci-dessous ce qui fonctionne pour moi ...

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

dans mon @ngmodule principal, j'ai ceci dans les fournisseurs ...

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

La référence à la classe Config est une variable de remplacement de Webpack au moment de la construction qui configure une carte de variables utilisées dans les modes Dev ou Prod.

Bonjour

J'ai pu atteindre la clé dynamique, comme par les commentaires @ jorrit-wehelp, mais dans mon scénario après la déconnexion de l'utilisateur et la connexion, la valeur agmKey ne se met pas à jour et ne peut pas voir la carte

ce que j'ai fait était comme dans notre composant de module, nous avons ajouté le code suivant
J'ai donc déplacé les class GoogleMapsConfig et {provide: LAZY_MAPS_API_CONFIG, useClass: GoogleMapsConfig} intérieur de la carte @component

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

@Injectable ();
La classe GoogleMapsConfig implémente LazyMapsAPILoaderConfigLiteral {
public apiKey: chaîne;
constructeur () {
console.log ('À L'INTÉRIEUR DES CARTES'); // Ceci n'est pas affiché dans la console
this.apiKey = _authService.currentUser () && _authService.currentUser (). agmKey? _authService.currentUser (). agmKey: '';
_authService.getMapKey $ .subscribe ((clé) => {
this.apiKey = clé;
})
}
}

@Composant({
sélecteur: 'map-comp',
templateUrl: './dyn-map.component.html',
styleUrls: ['./dyn-map.component.scss'],
fournisseurs: [{provide: LAZY_MAPS_API_CONFIG, useClass: GoogleMapsConfig}],
encapsulation: ViewEncapsulation.None
})

''
après la déconnexion et la connexion avec un autre utilisateur, le contrôle n'entre pas dans la classe GoogleMapsConfig que puis-je faire pour résoudre ce problème?

La solution de @ jorrit-wehelp fonctionnait, mais seulement par intermittence car j'avais une condition de concurrence où mon service qui renvoie la clé api ne la renvoyait pas toujours à temps pour leélément à essayer et à rendre. Afin de forcerpour attendre que la clé api soit retournée, j'ai simplement fait ceci:

constructeur de mon composant de carte:

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

Puis dans le balisage:

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

Je ne sais pas si cela s'appliquera à tout le monde ou si c'est plus au cas par cas, mais j'ai découvert que c'était le résultat du processus de compilation AOT d'Angular, par opposition à un problème avec agm lui-même. Voici un aperçu de la situation que j'ai eue.

Je voulais que la configuration de la clé d'API soit pilotée au lieu d'une chaîne codée en dur, de sorte que le déplacement dans différents environnements me permette d'utiliser différentes clés d'API et de surveiller l'utilisation de l'API. Pour ce faire, j'ai demandé à mon back-end .NET d'injecter du JavaScript avec la valeur dont j'avais besoin dans l'espace de noms global, stocké dans Example.Namespace.GoogleMapsApiKey . Dans cet esprit, voici mon code 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 {}

Je pensais que la création d'une définition de type pour une variable globale const avec la valeur dont j'avais besoin serait incluse lors du processus de construction AOT. Cependant, il s'avère que le compilateur AOT ne prend en charge qu'un sous-ensemble d'outils TypeScript , ce qui a empêché la variable d'être incluse au moment de la compilation. En fait, ce qui se passait était une erreur " Uniquement les variables et constantes initialisées " sans qu'une erreur soit émise par la CLI angulaire. Une fois que j'ai fait le changement pour utiliser une sorte de fournisseur LAZY_MAPS_API_CONFIG utilisant une classe que j'ai pu réussir.

Ce problème a été automatiquement marqué comme obsolète car il n'a pas eu d'activité récente. Il sera fermé si aucune autre activité ne se produit. Merci pour vos contributions.

Cette page vous a été utile?
0 / 5 - 0 notes

Questions connexes

Subhojit1992 picture Subhojit1992  ·  3Commentaires

supran2811 picture supran2811  ·  4Commentaires

marcelinobadin picture marcelinobadin  ·  3Commentaires

alexweber picture alexweber  ·  4Commentaires

ostapch picture ostapch  ·  4Commentaires