Angular 2: Importing Environment Based Services

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

I created a new environment called dev-mock that I can invoke with ...

ng serve --environment=mock

      

Then I set the provider in the module using 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 great, then the problem is what should I do when I want to inject this into another service or component, like ...

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's the correct approach?

+3


source to share


1 answer


Create an interface for MockApiService and ApiService for example. IApiService. If you want to replace them, there must be one.

Create a file with a marker and export it:

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

      

Then register your service somewhere with a token:



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

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

      

Finally, you can use it anywhere using the Inject () decorator applied in the 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 in the gice interface as a property type and using Inject () with an OpaqueToken to tell the dependency injector what it should put in.

+1


source







All Articles