Angular 2 Injected Service is undefined

LanceM picture LanceM · Mar 22, 2017 · Viewed 14.9k times · Source

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)
{

}
}

Answer

LanceM picture LanceM · Mar 22, 2017

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.