SillyPerson
SillyPerson

Reputation: 619

Angular Inject Service into Service : No Provider

I have two services in Angular:

MonitoringService.service.ts:

import { ClientAppSettingService } from './clientAppSettings.service';
import { Injectable, Inject } from '@angular/core';

@Injectable()
export class MonitoringService
{
  constructor(private _clientAppSettingService: ClientAppSettingService)
  {
    this.getclientAppSettings();
  }
  getclientAppSettings(): any {
    this._clientAppSettingService.getConfig().subscribe(result => {
    this.data = result;
    }, error => console.error(error));
  }

and ClientAppSetting.service.ts:

import { Injectable, Inject } from '@angular/core';
import { AppSettingsClient } from '../models/appSettingsClient';
import { HttpClient } from '@angular/common/http';

@Injectable()
export class ClientAppSettingService {
  appUrl: string = "";
  constructor(private http: HttpClient, @Inject('BASE_URL') baseUrl: string) {
    this.appUrl = baseUrl;
  }
  getConfig() {
    return this.http.get<AppSettingsClient>(this.appUrl + 'api/ClientAppSettings/Get');
  }
}

This is app.module.ts:

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { HttpClientModule } from '@angular/common/http';
import { RouterModule } from '@angular/router';
import { ClientAppSettingService } from './services/clientAppSettings.service';
import { HomeService } from './services/home.service';
import { AppComponent } from './app.component';
import { MonitoringService } from './services/monitoring.service';
import { HomeComponent } from './home/home.component';
import { EmbedReportComponent } from './embedReport/embedReport.component';
import { BaseComponent } from './base.component';
@NgModule({
  declarations: [
    AppComponent,
    HomeComponent,
    EmbedReportComponent,
    BaseComponent
  ],
  imports: [
    BrowserModule.withServerTransition({ appId: 'ng-cli-universal' }),
    HttpClientModule,
    FormsModule,
    RouterModule.forRoot([
      { path: '', component: HomeComponent, pathMatch: 'full' },
      { path: 'report', component: EmbedReportComponent }
    ])
  ],
  providers: [
    ClientAppSettingService,
    HomeService,
    ReportService,
    MonitoringService
    ],
  bootstrap: [AppComponent]
})
export class AppModule { }

I followed this , which says that you need to provide service in the provider of NgModule.

I also followed this, which says

Make sure you declare a provider for ClientAppSettingService before you declare a provider for MonitorningService

I also tried adding @Inject in my constructor as below:

constructor( @Inject(ClientAppSettingService) _clientAppSettingService: ClientAppSettingService)

However, I still receive error regarding No Provider:

ERROR Error: Uncaught (in promise): Error: No provider for ClientAppSettingService! (MonitoringService -> ClientAppSettingService) Error: No provider for ClientAppSettingService! (MonitoringService -> ClientAppSettingService)

Additional Information:

I have a base.component.ts which calls the MonitoringService:

import { MonitoringService } from './services/monitoring.service';
import { Component, ReflectiveInjector, OnInit } from '@angular/core';

@Component({
  template: ''
})
export class BaseComponent
{
  constructor(private _monitoringService: MonitoringService)
  {
    const injector = ReflectiveInjector.resolveAndCreate([
      MonitoringService
    ]);
    this._monitoringService = injector.get(MonitoringService);
  }

Then I extent other components with Base.component.ts to use the MonitorningService as below. For example home.component.ts uses MonitoringService as below:

import { Home } from '../models/home';
import { BaseComponent } from '../base.component';
import { MonitoringService } from '../services/monitoring.service';

@Component({
  selector: 'app-home',
  templateUrl: './home.component.html'
})

export class HomeComponent extends BaseComponent implements OnInit
{
  home: Home;

  constructor(private homeService: HomeService, private _monitorningService: MonitoringService)
  {
    super(_monitorningService);
  }

Upvotes: 14

Views: 20333

Answers (2)

Swoox
Swoox

Reputation: 3750

Let me explain it a little. You have two layers one layer is your component and the other layer is your module. What you can do is provide the ClientAppSettingService into the component:

 @Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
  providers: [ClientAppSettingService]
})

You have to remove it from your module and keep the other one there. Keep in mind that everywhere where you want to inject your service you have to provide it into the component.

Upvotes: 3

Kuldeep Singh
Kuldeep Singh

Reputation: 309

This is happening because you have not registered your Service in app.module.ts file. You need to set ClientAppSettingService into providers array in app.module.ts. it should look like

providers: [ClientAppSettingService]

of course you will have to import the same before using it into providers array.

Upvotes: 2

Related Questions