angulartypescripttypesdependency-injection

Extending Angular2+ services


I am trying to write a 'base' service with empty methods that should be overridden by other developers writing 'adapters' for different back-end systems

Here is my 'Base' authentication service:

import { Injectable } from '@angular/core';
import { Http} from '@angular/http';
import {constants} from '../../constants/constants';

@Injectable()
export class ApiAuthServiceProvider {

  constructor(public http: Http) {
    console.log('Hello Base class ApiAuthServiceProvider Provider');
  }

  getVersion(credentials): Promise <any> {
    throw constants.NOT_IMPLEMENTED;
  }

  getToken (credentials): Promise <any> {
    throw constants.NOT_IMPLEMENTED;
  }

  getCredentials(): any {
    // do some stuff which is generic
    // and will be part of the base implementation
  }
}

Here is my proposed adapter that extends this service for a specific backend:

import { Injectable } from '@angular/core';
import { Http , URLSearchParams} from '@angular/http';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/toPromise';
import {constants} from '../../../constants/constants';
import {ApiAuthServiceProvider} from '../../../providers/api-auth-service/api-auth-service';


@Injectable()
export class zmApiAuthServiceProvider extends ApiAuthServiceProvider {

  constructor(public http: Http) {
    super(http);
    console.log('Hello ZMApiAuthServiceProvider Provider');
   
  }

  getVersion(credentials): Promise <any> {
    return this.http.get (credentials.url+'/api/host/getVersion.json')
    .toPromise()
  }

  
  getToken(credentials): Promise <any> {
   // my stuff
 }
}

Here is how I am associating the adapter service in app.component.ts:

import {ApiAuthServiceProvider} from '../providers/api-auth-service/api-auth-service'
import {constants} from '../constants/constants';

// Classes for adapters in use
import {zmApiAuthServiceProvider} from '../adapters/zoneminder/providers/zm-api-auth-service';

@Component({
  templateUrl: 'app.html',
  providers: [
    {provide: ApiAuthServiceProvider, useClass: zmApiAuthServiceProvider}]
})

And finally, invocation in the constructor of app.components.ts:

constructor(public auth: ApiAuthServiceProvider) {
this.auth.getToken(credentials)
}

Trying to run this produces a whole bunch of errors:

Individual declarations in merged declaration 'ApiAuthServiceProvider' must be all exported or all local.
Import declaration conflicts with local declaration of 'ApiAuthServiceProvider'.
Module '"xxx/src/adapters/zm/providers/zm-api-auth-service"' has no exported member 'zmApiAuthServiceProvider'.

Am I approaching this incorrectly? Thanks.


Solution

  • Okay, I have no idea why this was not working when I posted - it's possible I did not save something!

    This approach works very well - it could either be a) magic b) my omission to save

    I'll go with magic.