How to create a custom Angular 4 service

I would like to create a service for reuse over several angular applications.

I am using angular-cli.

I want the service to be configured. In other words, give each application the ability to instantiate a service with different configuration parameters using DI.

The service will be hosted in a shared library, so it cannot import a specific file path from the parent application in order to get configuration parameters, it must receive them through DI.

I tried to follow the instructions here , as the article describes exactly the problem that I encountered, however I get an error message:

ERROR Error: No provider for String!
at injectionError (core.es5.js:1169)
at noProviderError (core.es5.js:1207)
at ReflectiveInjector_.webpackJsonp.../../../core/@angular/core.es5.js.ReflectiveInjector_._throwOrNull (core.es5.js:2649)
at ReflectiveInjector_.webpackJsonp.../../../core/@angular/core.es5.js.ReflectiveInjector_._getByKeyDefault (core.es5.js:2688)
at ReflectiveInjector_.webpackJsonp.../../../core/@angular/core.es5.js.ReflectiveInjector_._getByKey (core.es5.js:2620)
at ReflectiveInjector_.webpackJsonp.../../../core/@angular/core.es5.js.ReflectiveInjector_.get (core.es5.js:2489)
at resolveNgModuleDep (core.es5.js:9533)
at _createClass (core.es5.js:9572)
at _createProviderInstance$1 (core.es5.js:9544)
at resolveNgModuleDep (core.es5.js:9529)

Also from the .js zone:

zone.js:643 Unhandled Promise rejection: No provider for String! ; Zone: <root> ; Task: Promise.then ; Value: Error: No provider for String!

Here is my local code:

main.ts:

...
import { provideAuthService } from 'shared-library';
...
platformBrowserDynamic().bootstrapModule(AppModule, [provideAuthService('Good Day')]);

app.module.ts:

...
import { AuthService } from 'shared-library';

@NgModule({
  declarations: [
      ...
  ],
  imports: [
    ...
  ],
  providers: [
    AuthService
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }

and auth.service.ts:

...

export function provideAuthService(settings:string) {  
  return { provide: AuthService, useFactory: () => new AuthService(settings) 
}

@Injectable()
export class AuthService {
mgr: UserManager = new UserManager(this.settings);

    constructor(private settings:string='Hello') {
       ...
    }
}

, !

+4
1

, Angular, , .

:

export const APP_CONFIG = new InjectionToken<string>('AppConfig');

, . . , .

export interface AppConfig {
     name: string;
     baseUrl: string;
}

. forRoot(), . , , , ( ).

import { Injectable, NgModule, SkipSelf, Optional } from '@angular/core';
@NgModule({
     providers: [
         YourServiceClass
     ]
})
export class ServiceModule {
    public static forRoot(config: AppConfig) {
         return {
              ngModule: ServiceModule,
              providers: [
                  {provide: APP_CONFIG, useValue: config}
              ]
         };
    }

    public constructor(@Optional() @SkipSelf() parentModule: ServiceModule) {
         if(parentModule) {
             throw new Error('ServiceModule has already been imported.');
         }
    }
}

.

@Injectable()
export class YourServiceClass {
     public constructor(@Inject(APP_CONFIG) config: AppConfig) {
     }
}

, forRoot .

@NgModule({
    imports: [
        ServiceModule.forRoot({
             name: 'FooBar',
             baseUrl: 'http://www.example.com/'
        })
    ]
})
export class MainModule {}

, , forRoot . APP_CONFIG, . , , forRoot, , , .

, ServiceModule APP_CONFIG undefined. . ServiceModule , . , , .

, , , ServiceModule. , . . , , , .

+6

Source: https://habr.com/ru/post/1680603/


All Articles