Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

353
Visualizações
Angular 2: Import service based on environment

What is the best/proper way to import a service based on the current environment within an angular-cli project?

I have setup up a new environment called dev-mock which I can call with ...

ng serve --environment=mock

I then set up the provider in the module with useClass

app/app.module.ts ...

import {environment} from '../environments/environment';
import {ApiService} from './api/api.service';
import {MockApiService} from './api/mock/mock-api.service';

@NgModule({
  declarations: [
    AppComponent,
  ],
  imports: [
    BrowserModule,
    FormsModule,
    HttpModule
  ],
  providers: [
    {
      provide: ApiService,
      useClass: (environment.name === 'dev-mock') ? MockApiService : ApiService
    }
  ],
  bootstrap: [AppComponent]
})

This works fine, the problem then is what do I do when I want to inject that into another service or component, for example ...

app/ticket/ticket.service.ts

import {ApiService} from '../api/api.service'; // *** WHAT AM I TO DO HERE? ***

@Injectable()
export class TicketService {

  constructor(private api: ApiService, private http: Http) {
  }

}

Obviously my approach is wrong. What is the correct approach?

about 4 years ago · Santiago Trujillo
2 Respostas
Responde à pergunta

0

Create interface for MockApiService and ApiService eg. IApiService. If you want to interchange them there has to be one.

Create a file with token and export it:

import { OpaqueToken } from '@angular/core';
export let API_SERVICE = new OpaqueToken('api.service');

Then register your service somewhere using the token:

const apiServiceClass = (environment.name === 'dev-mock') ? MockApiService : ApiService;

providers: [{ provide: API_SERVICE, useClass: apiServiceClass }]

Finally you can use it in any place using Inject() decorator applied in constructor, eg.

import {IApiService} from '../api/iapi.service';
import { Inject, Injectable } from '@angular/core';

@Injectable()
export class TicketService {

  constructor(@Inject(API_SERVICE) private api: IApiService) {}
}

The trick is to gice interface as type of property and use Inject() with OpaqueToken to tell dependency injector what it should put.

about 4 years ago · Santiago Trujillo Relatório

0

In my libs, I am using an abstract Environment class that defines common environment variables.

export abstract class Environment {
  abstract readonly production: boolean;
  abstract readonly appUrls: {
    readonly public: string;
    readonly portal: string;
    readonly admin: string;
  };
}

Then I changed the environment.ts files to be as follows.

import { Environment } from '@my-lib-prefix/common';

class EnvironmentImpl implements Environment {
  production = false;
  appUrls = {
    public: 'http://localhost:4200',
    portal: 'http://localhost:4201',
    admin: 'http://localhost:4202'
  };
}

export const environment = new EnvironmentImpl();

The environment.prod.ts would of course be symmetric to the dev environment.ts. Then I provide the respective environment dependency, in the root app.module.ts for each of the Angular apps.

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { AppComponent } from './app.component';
import { Environment } from '@my-lib-prefix/common';
import { environment } from '../environments/environment';

@NgModule({
  declarations: [AppComponent],
  imports: [BrowserModule],
  providers: [{ provide: Environment, useValue: environment }],
  bootstrap: [AppComponent]
})
export class AppModule {}

Now any component can inject environment dependencies in a clean, and common manner.

import { Component } from '@angular/core';
import { Environment } from '@my-lib-prefix/common';

    @Component({
      selector: 'my-login',
      templateUrl: './my-login.component.html'
    })
    export class MyLoginComponent {
      constructor(private env: Environment) {}
    }

It enforces each environment.ts to implement the "common" environment variables defined in the abstract class. Also, each respective EnvironmentImpl can be extended with their own specific environment variables specific to the app. This approach seems very flexible and clean. Cheers!

about 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda