【问题标题】:inject one service into another and have access to the injected services members angular 7将一项服务注入另一项服务并可以访问注入的服务成员 Angular 7
【发布时间】:2019-11-04 16:17:30
【问题描述】:

我在这里阅读的所有内容:https://angular.io/guide/dependency-injection-in-action 使这看起来应该是可能的,但是当我尝试从另一个服务调用我注入的服务的方法时出现此错误:

TypeError:无法读取未定义的属性“isLoggedIn” 在 CatchSubscriber.handleError [作为选择器] (project.service.ts:30) 在 CatchSubscriber.error (catchError.js:29) 在 TapSubscriber._error (tap.js:56) 在 TapSubscriber.error (Subscriber.js:55) 在 MapSubscriber._error (Subscriber.js:75) 在 MapSubscriber.error (Subscriber.js:55) 在 FilterSubscriber._error (Subscriber.js:75) 在 FilterSubscriber.error (Subscriber.js:55) 在 MergeMapSubscriber.notifyError (OuterSubscriber.js:7) 在 InnerSubscriber._error (InnerSubscriber.js:14)

这是我的ProjectService,它正在注入我的UserService

import { Injectable } from '@angular/core';
import { HttpClient, HttpErrorResponse, HttpHeaders } from '@angular/common/http';
import { Observable, throwError, of } from 'rxjs';
import { catchError, tap, map } from 'rxjs/operators';
import { AuthHeader } from '../../Shared/Helpers/AuthHeader';
import { UserService } from '../../User/Services/user.service';

@Injectable({
  providedIn: 'root'
})
export class ProjectService {

  constructor(private http: HttpClient, private userService: UserService) {

  }
  private projectsApiEndPointRoot = '/api/ProjectApi/';
  test(): Observable<number> {
    return <Observable<number>>this.http.get<number>(this.projectsApiEndPointRoot + "getimages/8", { headers: AuthHeader.getAuthHeader() }).pipe(
      tap(data => console.log(data)),
      catchError(this.handleError)
    );
  }

  private handleError(err: HttpErrorResponse) {
    let errorMessage = '';
    if (err.error instanceof ErrorEvent) {
      errorMessage = `An error occurred: ${err.error.message}`;
    } else {
      if (err.status == 401 || err.status == 403) {
        console.log(this.userService.isLoggedIn());
      }
      else {
        errorMessage = `Server returned code: ${err.status}, error message is: ${err.message}`;
      }
    }
    console.error(errorMessage);
    return throwError(errorMessage);
  }
}

UserService 只是有一个方法应该返回布尔值,无论用户是否登录。我在几个组件上成功使用了相同的方法,但是当尝试从其他服务调用它时它不起作用。

这不可能吗?

编辑:添加一些UserService 进行演示:

import { Injectable } from '@angular/core';
import { HttpClient, HttpErrorResponse } from '@angular/common/http';
import { Observable, throwError, of, BehaviorSubject } from 'rxjs';
import { catchError, tap, map } from 'rxjs/operators';
import { EmailModel } from '../Models/EmailModel';
import { ILoginRequest } from '../Interfaces/ILoginRequest';
import { ILoginResponse } from '../Interfaces/ILoginResponse';
import { IRegistrationRequest } from '../Interfaces/IRegistrationRequest';
import { Router } from '@angular/router';


@Injectable({
  providedIn: 'root'
})
export class UserService {
  constructor(private http: HttpClient, private router: Router) { }
  private usersApiEndPointRoot = 'api/UserApi/';

  private loggedIn = false;
  ...

  isLoggedIn() {
    return this.loggedIn;
  }


  private handleError(err: HttpErrorResponse) {
    let errorMessage = '';
    if (err.error instanceof ErrorEvent) {
      errorMessage = `An error occurred: ${err.error.message}`;
    } else {
      errorMessage = `Server returned code: ${err.status}, error message is: ${err.message}`;
    }
    console.error(errorMessage);
    return throwError(errorMessage);
  }
}

【问题讨论】:

  • 对我来说看起来不错。这当然是可能的。可以把UserService的代码也贴一下吗?
  • 如果你在构造函数中也做了一个console.log(this.userService),用户服务是否未定义?
  • 尝试更改方法签名:private handleError = (err: HttpErrorResponse) =&gt; {...} 可能与作用域有关
  • 是的,UserService 未定义。查看我的编辑,我已将其重要部分添加到我的 OP。

标签: angular typescript angular-services angular-components


【解决方案1】:

问题是您在用户服务上传递函数。当它被调用时,this 的值将是窗口。

不要将函数传递给 catchError 函数,而是使用 lambda 函数,以便保留它。对test() 方法进行以下更改,您的问题将得到解决:

test(): Observable<number> {
  return <Observable<number>>this.http.get<number>(this.projectsApiEndPointRoot + 
      "getimages/8", { headers: AuthHeader.getAuthHeader() }).pipe(
    tap(data => console.log(data)),
    catchError(err => this.handleError(err)) // <--
  );
}

【讨论】:

  • 确实如此。你也可以使用catchError(this.handleError.bind(this))
  • 这为我解决了。我讨厌我不完全理解的东西,所以你介意再详细说明一下吗?为什么传递catchError() 一个调用handleError() 的内联函数会保留我的UserService 实例?
  • 当您只是将引用传递给方法时,该方法不知道this 的值应该是什么。无论this 在当前堆栈中使用什么。这是一个演示(你需要查看你的控制台):stackblitz.com/edit/typescript-egphws
  • @DanielGimenez 这是一个非常有用的演示。感谢您抽出宝贵时间。
【解决方案2】:

您需要在 catchError 中使用箭头函数才能使用类上下文 this。

catchError((err) => this.handleError(err))

否则上下文将丢失。

【讨论】:

    【解决方案3】:

    我也会将我的评论作为答案,因为它与其他答案有点不同。

    像这样更改方法的签名

    private handleError = (err: HttpErrorResponse) =&gt; {...}

    然后,如果您愿意,您可以保持 catchError(this.handleError) 不变。

    【讨论】:

      猜你喜欢
      • 2020-03-14
      • 2013-12-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-08-24
      • 2016-04-20
      • 2014-01-27
      相关资源
      最近更新 更多