Ionic2 / Angular2: lee un archivo de configuración personalizado

Estoy trabajando en un proyecto de ionic2 y necesito crear un nuevo archivo de configuración de JSON personalizado. Encontré algunos tutoriales para crear uno y acceder a él a través de http.get, pero creo que es extraño llamarlo a través de una solicitud de obtención. Lo quiero en la carpeta raíz (donde están todos los JSON de configuración) y abro / leo el archivo directamente.

No sé si es posible, ¿o incluso recomendado? Es por eso que estoy publicando aquí para tener algunas opiniones y soluciones 🙂

Gracias

Personalmente, no me gusta leer el archivo config.json usando la forma http.get para manejar la información de configuración, y aunque debe haber otra manera de simplemente incluir y leer el archivo json en tu código, ya que estamos usando Angular2 y Typescript, ¿por qué no usar clases, interfaces y hacerlo de una manera más elegante?

Lo que le mostraré a continuación puede parecer más complicado de lo que debería al principio (aunque después de leerlo lo encontrará muy sencillo y fácil de entender), pero cuando comencé a aprender Angular2 vi un ejemplo de cómo manejaron los archivos de configuración en la guía de Inyección de Dependencia y yo lo seguí en las aplicaciones en las que trabajé para manejar la información de configuración (como puntos finales API, valores predeterminados, etc.).

De acuerdo con los documentos:

Dependencias no de clase

[…]

Las aplicaciones a menudo definen objetos de configuración con muchos datos pequeños (como el título de la aplicación o la dirección de un punto final de API web), pero estos objetos de configuración no siempre son instancias de una clase.

Una solución para elegir un token de proveedor para dependencias que no sean de clase es definir y usar un OpaqueToken

Por lo tanto, necesitaría definir un objeto de configuración con las URL y demás, y luego un OpaqueToken para poder usarlo al inyectar el objeto con su configuración.

Incluí toda mi configuración en el archivo app-config.ts

 // Although the ApplicationConfig interface plays no role in dependency injection, // it supports typing of the configuration object within the class. export interface ApplicationConfig { appName: string; apiEndpoint: string; } // Configuration values for our app export const MY_CONFIG: ApplicationConfig = { appName: 'My new App', apiEndpoint: 'http://www...' }; // Create a config token to avoid naming conflicts export const MY_CONFIG_TOKEN = new OpaqueToken('config'); 

Lo que OpaqueToken es puede ser confuso al principio, pero solo una cadena que evitará conflictos de nombres cuando se inyecte este objeto. Puedes encontrar una publicación increíble sobre esto aquí .

Entonces, solo necesita incluirlo en la página que necesita de esta manera:

 import { NavController } from 'ionic-angular/index'; import { Component, OpaqueToken, Injectable, Inject } from "@angular/core"; // Import the config-related things import { MY_CONFIG_TOKEN, MY_CONFIG, ApplicationConfig } from 'app-config.ts'; @Component({ templateUrl:"home.html", providers: [{ provide: MY_CONFIG_TOKEN, useValue: MY_CONFIG }] }) export class HomePage { private appName: string; private endPoint: string; constructor(@Inject(MY_CONFIG_TOKEN) private config: ApplicationConfig) { this.appName = config.appName; this.endPoint = config.apiEndpoint; } } 

Tenga en cuenta cómo incluirlo en la matriz de providers

 providers: [{ provide: MY_CONFIG_TOKEN, useValue: MY_CONFIG }] 

Y cómo decirle al inyector cómo debería obtener la instancia del objeto config

 @Inject(MY_CONFIG_TOKEN) config: ApplicationConfig 

ACTUALIZAR

OpaqueToken ha quedado obsoleto desde la versión 4.0.0 porque no es compatible con la información de tipo, en su lugar, use InjectionToken< ?> .

Entonces, en lugar de estas líneas:

 import { OpaqueToken } from '@angular/core'; // Create a config token to avoid naming conflicts export const MY_CONFIG_TOKEN = new OpaqueToken('config'); 

Ahora deberíamos usar

 import { InjectionToken } from '@angular/core'; // Create a config token to avoid naming conflicts export const MY_CONFIG_TOKEN = new InjectionToken('config'); 

Después de leer y leer diferentes soluciones terminé usando esta implementación de hacky. Con suerte, pronto habrá una solución agradable y nativa disponible:

 import { NgModule } from '@angular/core'; import { environment as devVariables } from './environment.dev'; import { environment as testVariables } from './environment.test'; import { environment as prodVariables } from './environment.prod'; export function environmentFactory() { const location = window.location.host; switch (location) { case 'www.example.org': { return prodVariables; } case 'test.example.org': { return testVariables; } default: { return devVariables; } } } @NgModule({ providers: [ { provide: 'configuration', useFactory: environmentFactory } ] }) export class EnvironmentsModule {} 

y luego donde sea necesario, por ejemplo:

 import { Injectable, Injector, Inject } from '@angular/core'; import { AuthenticationService } from '../authentication'; @Injectable() export class APIService { private http: Http; private apiURL: string; protected authentication: AuthenticationService; constructor( public injector: Injector, @Inject('configuration') public configuration: any ) { this.http = injector.get(Http); this.authentication = injector.get(AuthenticationService); this.apiURL = configuration.apiURL; }; ...