Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular 2 Injected Service is undefined

Why is my service (this.loggerService) undefined in my DataHandlerService when it has been injected? I thought dependency injection took care of this. My loggerService works in other services. Please help me realize where I am going wrong. My DataHandlerService code below:

import { Injectable } from '@angular/core';
import { Http, Response } from '@angular/http';
import { Observable } from 'rxjs/Observable';
import { LoggerService } from './logger.service';

@Injectable()

export class DataHandlerService 
{
constructor(private loggerService: LoggerService)
{

}

extractData(res: Response)
{
    let body = res.json();
    return body || {};
}


handleHttpError(error: any)
{
    let errMsg = (error.message) ? error.message : error.status ? `${error.status} - ${error.statusText}` : 'Server error';

    if (errMsg && this.loggerService)  //Why is this.loggerService always undefined?
    {
        this.loggerService.error(errMsg);
    }

    return Observable.throw(errMsg);
}
}

My LoggerService code below:

import { Injectable } from '@angular/core';
import { Http, Headers, Response } from '@angular/http';
import { Observable } from 'rxjs/Observable';
import { ConfigurationService } from './configuration.service';

@Injectable()

export class LoggerService 
{
constructor(private http: Http, private configurationService: ConfigurationService)
{

}

public fatal(msg: string)
{
    if (msg)
    {
        this.log(msg, "Fatal");
    }
}

public debug(msg: string)
{
    if (msg)
    {
        this.log(msg, "Debug");
    }
}

public info(msg: string)
{
    if (msg)
    {
        this.log(msg, "Info");
    }
}

public warn(msg: string)
{
    if (msg)
    {
        this.log(msg, "Warn");
    }
}

public error(msg: string)
{
    if (msg)
    {
        this.log(msg, "Error");
    }
}

private log(msg: string, logLevel: string)
{
    if (msg && logLevel && this.configurationService && this.configurationService.coreSettings)
    {
        let headers = new Headers();
        headers.append('Content-Type', 'application/json');
        headers.append('Accept', 'application/json');

        let loggingInfo: LoggingInfo = { "message": msg, "logLevel": logLevel, "sourceName": "CoreIV", "logDirectory": this.configurationService.coreSettings.logDirectory };

        this.http.post(this.configurationService.coreSettings.logbookUrl + "/rest/LogMessage", { loggingInfo }, { headers: headers })
            .toPromise()
            .then(res => this.extractData(res))
            .catch(err => this.handleHttpError(err));
    }
}

private extractData(res: Response)
{
    let body = res.json();
    return body || {};
}

private handleHttpError(error: any)
{
    let errMsg = (error.message) ? error.message :
        error.status ? `${error.status} - ${error.statusText}` : 'Server error';
    return Observable.throw(errMsg);
}



}

export interface LoggingInfo
{
    message: string,
    logLevel: string,
    sourceName: string,
    logDirectory: string

}

My App.Module code below:

import { NgModule, APP_INITIALIZER, ErrorHandler } from '@angular/core';
import { LocationStrategy, HashLocationStrategy } from '@angular/common';
import { HttpModule, JsonpModule, Jsonp } from '@angular/http';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule, FormGroup, FormControl, ReactiveFormsModule }   from '@angular/forms';
import { routing, appRoutingProviders } from './app.routing';
import { AppConfig } from './app.config';

import { AppComponent } from './app.component';
import { HomeComponent } from './home/home.component';
import { AppErrorHandler, LOGGING_ERROR_HANDLER_OPTIONS,     LOGGING_ERROR_HANDLER_PROVIDERS } from './app.error-handler';

import { AppService } from './app.service';
import { ConfigurationService } from './shared/services/configuration.service';
import { DataHandlerService } from './shared/services/data-handler.service';
import { LoggerService } from './shared/services/logger.service';
import { AuthGuard } from './auth-guard.service';

export function init_app(appConfig: AppConfig, configurationService: ConfigurationService, loggerService: LoggerService)
{
// Do initiating of services that are required before app loads
// NOTE: this factory needs to return a function (that then returns a promise)

return appConfig.load()
    .then((res) =>        
    {
        configurationService.coreSettings = appConfig.config;
    })
    .catch((err) =>
    {
        loggerService.error(err);
    });
}

@NgModule({
imports: [
    BrowserModule,
    FormsModule,
    routing,
    HttpModule,
    JsonpModule
],
exports: [

],
declarations: [
    HomeComponent,
    AppComponent
],
providers: [
    HttpModule,
    ConfigurationService,
    LoggerService,
    { provide: LocationStrategy, useClass: HashLocationStrategy },
    LOGGING_ERROR_HANDLER_PROVIDERS,
    {
        provide: LOGGING_ERROR_HANDLER_OPTIONS,
        useValue: {
            rethrowError: false,
            unwrapError: true
        }
    },       
    appRoutingProviders,
    AuthGuard,    
    DataHandlerService,
    AppConfig,     
    {
        provide: APP_INITIALIZER,
        useFactory: init_app,
        deps: [AppConfig, ConfigurationService, LoggerService],
        multi: false
    }
    ],
    bootstrap: [AppComponent, appRoutingProviders]
   })


export class AppModule
{
constructor(private httpModule: HttpModule)
{

}
}
like image 472
LanceM Avatar asked Mar 22 '17 15:03

LanceM


People also ask

What is Injectable() in Angular service?

The @Injectable() decorator defines a class as a service in Angular and allows Angular to inject it into a component as a dependency. Likewise, the @Injectable() decorator indicates that a component, class, pipe, or NgModule has a dependency on a service.

What is dependency injection DI in Angular 2?

Dependency injection, or DI, is one of the fundamental concepts in Angular. DI is wired into the Angular framework and allows classes with Angular decorators, such as Components, Directives, Pipes, and Injectables, to configure dependencies that they need.

What is Injectable class in Angular?

@Injectable() lets Angular know that a class can be used with the dependency injector. @Injectable() is not strictly required if the class has other Angular decorators on it or does not have any dependencies.

What is ioc in Angular?

This is termed as IOC(Inversion of Control) where control is being inverted to the external entity. Angular offers such a system that helps not only to register but also to instantiate component dependencies.


1 Answers

I found out the solution to this issue. The answer in the post angular 2 - Injected service in http error handler pointed me in the right direction. I was using the following:

        .map(this.dataHandler.extractData)
        .catch(this.dataHandler.handleHttpError);

but should use:

        .map(res => this.dataHandler.extractData(res))
        .catch(err => this.dataHandler.handleHttpError(err));

For some reason the lambdas are needed.

like image 58
LanceM Avatar answered Oct 14 '22 21:10

LanceM