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);
}
Angular provides the ability for you to inject a service into a component to give that component access to the service. The @Injectable() decorator defines a class as a service in Angular and allows Angular to inject it into a component as a dependency.
We must tell Angular to instantiate Service1 to be available (instatiated) before Service2. Hence, we declare it as a provider into our module. In this small example application, we have only one module, the app.
If you want to use angular services (and Http is an angular service) you must inject them as I told above as a constructor attribute to another service / component , which means if you want to use Http you need to have your service injectable. So the answer is no, you can't do it in a nice way.
Angular Creates the Module Injector tree when the Application starts. At the top of the Module Injector tree, Angular creates an instance of Null Injector . The Null Injector always throws an error unless we decorate the dependency with the Optional decorator.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With