Javascript Angular HttpInterceptor-任何注入的服务返回未定义的TypeError
问题: 我无法将任何服务注入HttpInterceptor的构造函数中。我尝试注入服务的任何服务都会遇到以下错误:Javascript Angular HttpInterceptor-任何注入的服务返回未定义的TypeError,javascript,angular,typescript,angular-http-interceptors,Javascript,Angular,Typescript,Angular Http Interceptors,问题: 我无法将任何服务注入HttpInterceptor的构造函数中。我尝试注入服务的任何服务都会遇到以下错误: TypeError:无法设置未定义的属性“authenticationService” 这甚至适用于一个虚拟的foo服务,它只有一个功能bar,并且没有向其中注入额外的依赖项 代码 拦截器 对于质疑棱角版本的人 已执行的研究/故障排除: 我发现了各种SO帖子,并描述了在注入包含HttpClient引用的服务时出现的问题,这将导致循环依赖性错误,从而导致未定义,而authentica
TypeError:无法设置未定义的属性“authenticationService”
这甚至适用于一个虚拟的foo
服务,它只有一个功能bar
,并且没有向其中注入额外的依赖项
代码
拦截器
对于质疑棱角版本的人
已执行的研究/故障排除:
我发现了各种SO帖子,并描述了在注入包含HttpClient引用的服务时出现的问题,这将导致循环依赖性错误,从而导致未定义,而authenticationService确实有对HttpClient的引用。然而,根据帖子,这是固定在一个角5补丁。正如你所看到的,我目前在这个项目中使用Angular 7
我尝试按照这些说明操作,而不是将authenticationService
注入构造函数,而是注入一个注入器,然后执行:
this.authenticationService=this.injector.get(authenticationService)代码>
这将导致以下错误:
TypeError:无法设置未定义的属性“injector”
我还尝试将HttpInterceptor的app.module.ts提供程序更改为以下内容:
{provide:HTTP\u拦截器,useFactory:Interceptor,multi:true,deps:[AuthenticationService]}
这再次导致了相同的未定义错误
结论:
我为这本小说道歉,但我想确保每个人都有所有可能的信息来帮助解决这个让我头疼了3天的问题。提前谢谢大家 我遇到了与您相同的问题,我通过在模块声明中从useFactory
切换到useClass
解决了这个问题:
这是一个有效的7.1代码
{
提供:HTTP_拦截器,
useFactory(路由器:路由器,authenticationStorageService:authenticationStorageService){
//这里有很多东西
返回新的AuthInterceptor(路由器、authenticationStorageService);
},
多:是的,
deps:[路由器、身份验证存储服务]
},
它被折成8角。扔掉工厂解决了这个问题:
{
提供:HTTP_拦截器,
useClass:AuthInterceptor,
多:是的,
deps:[路由器、身份验证存储服务]
},
不过,我不得不改变类构造函数中的工厂逻辑。工厂方法更为灵活,因为您可以不时更改返回的实例,但在标准情况下可能有些过分。您在拦截器中使用的服务本身是否需要HttpClient
?这不应该是useClass:Interceptor
?useClass:Interceptor
,并删除both@jonrsharpe哦,我的上帝,我怎么没有看到…你是对的,应该是useClass,而不是useFactory…这样做(还删除了提供的“根”-谢谢William)解决了问题…非常感谢。如果你想快速给出答案,我想把它标记为正确的,这样就没有人需要处理我刚才犯的愚蠢错误了。@WilliamLohan是的,我也这么做了,但是简单地改为useClass而不是useFactory就解决了我的问题。没错,它可以工作,但是你在根目录中提供了拦截器
作为它自己,作为HTTP_拦截器
,现在我想这并不坏,只是不需要,除非你需要在其他地方注入拦截器
(如果是这种情况,您可能必须使用useExisting
将其保持为单例)
import { Injectable, Injector } from '@angular/core';
import {
HttpRequest,
HttpHandler,
HttpEvent,
HttpInterceptor
} from '@angular/common/http';
import { AuthenticationService } from '../authentication/authentication.service';
import { Observable } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class Interceptor implements HttpInterceptor {
constructor(private authenticationService: AuthenticationService) { }
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
if (request.url.includes(location.hostname) && this.authenticationService.getToken()) {
console.log('Headers added to the HTTP Request');
request = request.clone({
setHeaders: {
Authorization: `Bearer ${this.authenticationService.getToken()}`
}
});
}
return next.handle(request);
}
}
import { OnInit, Injectable } from '@angular/core';
import { AuthServiceConfig, AuthService as SocialAuthService, FacebookLoginProvider, GoogleLoginProvider, SocialUser} from 'angularx-social-login';
import { HttpClient, HttpRequest } from '@angular/common/http';
import { BehaviorSubject, Observable } from 'rxjs';
import { environment } from '../../../environments/environment';
import { JwtHelperService } from '@auth0/angular-jwt';
@Injectable( { providedIn: "root" } )
export class AuthenticationService implements OnInit{
jwtHelper: JwtHelperService = new JwtHelperService();
socialLoginConfig: AuthServiceConfig;
loggedIn: BehaviorSubject<Boolean> = new BehaviorSubject<Boolean>(false);
loggedIn$: Observable<Boolean> = this.loggedIn.asObservable();
user: BehaviorSubject<SocialUser> = new BehaviorSubject(null);
user$: Observable<SocialUser> = this.user.asObservable();
cachedRequests: Array<HttpRequest<any>> = [];
constructor(private socialAuthService: SocialAuthService, private http: HttpClient) { }
ngOnInit() {
this.socialAuthService.authState.subscribe((user) => {
this.user.next(user);
this.loggedIn.next((user != null));
});
}
provideConfig() {
return this.socialLoginConfig;
}
getToken(): string {
return localStorage.getItem('token');
}
refreshToken(): void {
// Need to add a call to refresh the token (JWT) to the backend.
}
isAuthenticated(): boolean {
const token = this.getToken();
return token != null && !this.jwtHelper.isTokenExpired(token);
}
collectFailedRequest(request): void {
this.cachedRequests.push(request);
}
retryFailedRequests(): void {
// Once the token has been refreshed, we can send previous failed requests from the cahcedRequests array...
}
signInWithGoogle(cb): void {
this.socialAuthService.signIn(GoogleLoginProvider.PROVIDER_ID).then(
(userData) => { //on success
console.log('google', userData);
this.user.next(userData);
this.sendToRestApiMethod(userData.idToken, 'google', cb);
}
).catch(err => {
console.log('Error logging into Google Services:', err);
});
}
signInWithFB(cb): void {
this.socialAuthService.signIn(FacebookLoginProvider.PROVIDER_ID).then(
(userData) => { //on success
console.log('facebook', userData);
this.user.next(userData);
this.sendToRestApiMethod(userData.authToken, 'facebook', cb);
}
).catch(err => {
console.log('Error logging into Facebook Services:', err);
});
}
signOut(): void {
this.socialAuthService.signOut();
this.user.next(null);
}
sendToRestApiMethod(token: string, provider: string, cb) : void {
this.http.post(environment.apiBaseUrl +'oauth2/authorization/' + provider, { token: token } )
.subscribe(jwt => {
console.log('login was successful', jwt);
localStorage.setItem('token', jwt['jwt']);
cb();
}, onFail => {
console.log('login was unsuccessful', onFail);
//show an error message
}
);
}
}
import { environment } from '../environments/environment';
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { LoginComponent } from './modules/public/pages/login/login.component';
import { SocialLoginModule, AuthServiceConfig } from "angularx-social-login";
import { GoogleLoginProvider, FacebookLoginProvider } from "angularx-social-login";
import { NavbarComponent } from './shared/components/navbar/navbar.component';
import { FooterComponent } from './shared/components/footer/footer.component';
import { HomeComponent } from './modules/public/pages/home/home.component';
import { UserComponent } from './modules/secure/pages/user/user.component';
import { HttpClientModule, HTTP_INTERCEPTORS} from '@angular/common/http';
import { Interceptor } from './core/interceptors/interceptor';
import { DashboardComponent } from './modules/secure/pages/dashboard/dashboard.component';
const socialLoginConfig = new AuthServiceConfig([
{ id: GoogleLoginProvider.PROVIDER_ID,
provider: new GoogleLoginProvider(environment.google.clientid) },
{ id: FacebookLoginProvider.PROVIDER_ID,
provider: new FacebookLoginProvider(environment.facebook.appid) }
]);
export function provideConfig() {
return socialLoginConfig;
}
@NgModule({
declarations: [
AppComponent,
HomeComponent,
LoginComponent,
UserComponent,
NavbarComponent,
FooterComponent,
DashboardComponent
],
imports: [
BrowserModule,
BrowserAnimationsModule,
AppRoutingModule,
SocialLoginModule,
HttpClientModule
],
providers: [
{ provide: AuthServiceConfig, useFactory: provideConfig },
{ provide: HTTP_INTERCEPTORS, useFactory: Interceptor, multi: true }
],
bootstrap: [AppComponent]
})
export class AppModule { }
Angular CLI: 7.2.3
Node: 11.7.0
OS: darwin x64
Angular: 7.2.2
... animations, cdk, common, compiler, compiler-cli, core, forms
... language-service, platform-browser, platform-browser-dynamic
... router
Package Version
-----------------------------------------------------------
@angular-devkit/architect 0.12.3
@angular-devkit/build-angular 0.12.3
@angular-devkit/build-optimizer 0.12.3
@angular-devkit/build-webpack 0.12.3
@angular-devkit/core 7.2.3
@angular-devkit/schematics 7.2.3
@angular/cli 7.2.3
@ngtools/webpack 7.2.3
@schematics/angular 7.2.3
@schematics/update 0.12.3
rxjs 6.3.3
typescript 3.2.4
webpack 4.28.4