Angular2:DI问题 - 将服务注入另一个服务会导致服务未定义

时间:2016-08-09 21:44:09

标签: angular dependency-injection

我正在进行Angular 2.0.0-rc.4项目,并且我遇到了依赖注入问题。

我有通知服务:

import { BehaviorSubject } from 'rxjs/BehaviorSubject';

import { Notification } from '../../notifications/notification.model'

export class NotificationService {
  private notificationsSource: BehaviorSubject<Notification[]>;
  private dataStore: { notifications: Notification[] }

  constructor() {
    this.dataStore = { notifications: [] };
    this.notificationsSource = new BehaviorSubject<Notification[]>([]);
  }

  // Additional code //

}

该项目使用JwtAuthHttp,我们将其延伸到AuthHttp。我在这里注入了NotificationService来通知错误:

import { Injectable } from '@angular/core';
import {
  Http,
  Request,
  Response,
  RequestOptionsArgs 
} from '@angular/http';
import { Router } from '@angular/router';
import { AuthHttp as JwtAuthHttp, AuthConfig } from 'angular2-jwt';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/do';

import { NotificationService } from './notification-service';

@Injectable()
export class AuthHttp extends JwtAuthHttp {
  constructor(
    options: AuthConfig,
    http: Http,
    private router: Router,
    private notificationService: NotificationService
  ) { super(options, http); }

  // Additional code //

  handleError(err: Response) {
    this.notificationService.add(err.json(), 'error');
    return Observable.throw(err)
  }
}

AuthHttpNotificationService都被添加为main.ts文件中的单身提供商:

import { APP_BASE_HREF } from '@angular/common';
import { enableProdMode, provide } from '@angular/core';
import { disableDeprecatedForms, provideForms } from '@angular/forms';
import { Router } from '@angular/router';
import { Http, HTTP_PROVIDERS } from '@angular/http';
import { bootstrap } from '@angular/platform-browser-dynamic';
import { Cookie } from 'ng2-cookies';
import { AuthConfig } from 'angular2-jwt';

import { APP_ROUTER_PROVIDERS } from './app.routes';
import { NotificationService } from './shared/services/notification.service';
import { AuthHttp } from './shared/services/auth-http';
import { AppComponent } from './app.component';

if ('<%= ENV %>' === 'prod') { enableProdMode(); }

bootstrap(AppComponent, [
  disableDeprecatedForms(),
  provideForms(),
  APP_ROUTER_PROVIDERS,
  HTTP_PROVIDERS,
  provide(APP_BASE_HREF, { useValue: '<%= APP_BASE %>' }),
  provide(AuthHttp, {
    useFactory: (http: Http, router: Router, notificationService: NotificationService) => {
      return new AuthHttp(new AuthConfig({
        noJwtError: true,
        tokenName: 'auth_token',
        tokenGetter: (() => Cookie.get('auth_token'))
      }), http, router, notificationService);
    },
    deps: [Http, Router, NotificationService]
  }),
  NotificationService
]);

我希望在handleError上使用AuthHttp方法作为我的服务,作为处理服务器错误通知的一般方法(例如以下PermissionService

import { Injectable } from '@angular/core';
import { Headers, RequestOptions } from '@angular/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/share';
import 'rxjs/add/observable/from';
import 'rxjs/add/operator/catch';
import 'rxjs/add/operator/map';

import { Config, AuthHttp, NotificationService } from '../../shared/index';
import { UserPermission } from './';
import { User } from './';

@Injectable()
export class PermissionService {
  public headers:Headers;
  private baseUrl:string = Config.API_URL;

  constructor(
    private http: AuthHttp,
    private notificationService: NotificationService
  ) { }

  getUserPermission(username: string): Observable<UserPermission> {
   return this.http.get(`${this.baseUrl}/user_permissions/${username}`)
    .map(response => response.json())
    .catch(this.http.handleError)
  }

  // Additional code //
}

但是,当发生服务器错误时,我收到以下错误:

  

TypeError:无法读取属性&#39;添加&#39;未定义的   在CatchSubscriber.AuthHttp.handleError [作为选择器]

因此,由于某种原因,NotificationService未被正确注入。我已经搜索了好几个小时的答案,但无法弄清楚是什么问题。

1 个答案:

答案 0 :(得分:0)

我通过更改catch中的getUserPermission来解决此问题:

.catch(this.http.handleError)

为:

.catch(err => this.http.handleError(err))

通过赋予catch函数,它似乎没有使用this.http的实例来调用该函数,而只是将该函数作为独立函数运行。实际上调用this.http上的函数没有给我带来任何问题。