将一项服务注入另一项服务,并可以访问注入的服务成员 angular 7
inject one service into another and have access to the injected services members angular 7
我在这里阅读的所有内容:https://angular.io/guide/dependency-injection-in-action 使这看起来应该是可能的,但是当我尝试从另一个服务调用我注入的服务的方法时出现此错误:
TypeError: Cannot read property 'isLoggedIn' of undefined
at CatchSubscriber.handleError [as selector] (project.service.ts:30)
at CatchSubscriber.error (catchError.js:29)
at TapSubscriber._error (tap.js:56)
at TapSubscriber.error (Subscriber.js:55)
at MapSubscriber._error (Subscriber.js:75)
at MapSubscriber.error (Subscriber.js:55)
at FilterSubscriber._error (Subscriber.js:75)
at FilterSubscriber.error (Subscriber.js:55)
at MergeMapSubscriber.notifyError (OuterSubscriber.js:7)
at 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
只是有一个方法应该 return 布尔值用户是否登录。我在几个组件上成功使用了相同的方法,但是在尝试时它不起作用从其他服务调用它。
这不可能吗?
编辑:为演示添加 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);
}
}
您需要在 catchError 中使用箭头函数才能使用 class 上下文 this。
catchError((err) => this.handleError(err))
否则上下文丢失。
问题是您在用户服务上传递函数。当它被调用时,this
的值将是 window.
不要将函数传递给 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)) // <--
);
}
我也会把我的评论作为答案,因为它与其他答案有点不同。
像这样更改方法的签名
private handleError = (err: HttpErrorResponse) => {...}
然后你可以保持catchError(this.handleError)
原样。
我在这里阅读的所有内容:https://angular.io/guide/dependency-injection-in-action 使这看起来应该是可能的,但是当我尝试从另一个服务调用我注入的服务的方法时出现此错误:
TypeError: Cannot read property 'isLoggedIn' of undefined at CatchSubscriber.handleError [as selector] (project.service.ts:30) at CatchSubscriber.error (catchError.js:29) at TapSubscriber._error (tap.js:56) at TapSubscriber.error (Subscriber.js:55) at MapSubscriber._error (Subscriber.js:75) at MapSubscriber.error (Subscriber.js:55) at FilterSubscriber._error (Subscriber.js:75) at FilterSubscriber.error (Subscriber.js:55) at MergeMapSubscriber.notifyError (OuterSubscriber.js:7) at 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
只是有一个方法应该 return 布尔值用户是否登录。我在几个组件上成功使用了相同的方法,但是在尝试时它不起作用从其他服务调用它。
这不可能吗?
编辑:为演示添加 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);
}
}
您需要在 catchError 中使用箭头函数才能使用 class 上下文 this。
catchError((err) => this.handleError(err))
否则上下文丢失。
问题是您在用户服务上传递函数。当它被调用时,this
的值将是 window.
不要将函数传递给 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)) // <--
);
}
我也会把我的评论作为答案,因为它与其他答案有点不同。
像这样更改方法的签名
private handleError = (err: HttpErrorResponse) => {...}
然后你可以保持catchError(this.handleError)
原样。