gpt4 book ai didi

angular - 我的拦截器上未定义构造函数变量(Angular 8)

转载 作者:行者123 更新时间:2023-12-04 08:13:11 25 4
gpt4 key购买 nike

我有一个名为拦截器的服务,它可以获取后端发送的所有错误响应。在这个服务上,我有一个名为 AuthService 的服务(向后端发出申请的服务),它在我的构造函数变量上声明。我使用这个另一个服务来调用向用户显示消息的方法。
同时,当拦截器被触发时,AuthService 未定义,并且我的消息没有显示。
在尝试解决该问题时,我尝试在 appModule 的提供者上声明 authService。它解决了未定义的问题,但出现了另一个问题。因此,我得出结论,这不是解决方案。
下面是我的字体:
拦截器.ts

import { LoadingController } from '@ionic/angular';
import { Injectable } from '@angular/core';
import {
HttpEvent,
HttpHandler,
HttpInterceptor,
HttpRequest,
HttpHeaders,
HttpErrorResponse
} from '@angular/common/http';

import { BehaviorSubject, throwError, Observable } from 'rxjs';
import { catchError } from 'rxjs/operators';
import { Router } from '@angular/router';
import { AuthService } from '../services/auth.service';

@Injectable()
export class HTTPStatus {
private requestInFlight$: BehaviorSubject<boolean>;

constructor() {
this.requestInFlight$ = new BehaviorSubject(false);
}
setHttpStatus(inFlight: boolean) {
this.requestInFlight$.next(inFlight);
}
getHttpStatus(): Observable<boolean> {
return this.requestInFlight$.asObservable();
}
}

@Injectable()
export class Interceptor implements HttpInterceptor {

constructor(
private _loadingController: LoadingController,
private _authService: AuthService, //This is the variable that comes undefined
private _router: Router
) {

}

intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return this.handleAccess(request, next);
}

private handleAccess(request: HttpRequest<any>, next: HttpHandler):
Observable<HttpEvent<any>> {
const token = JSON.parse(localStorage.getItem('currentToken'));
let changedRequest = request;
// HttpHeader object immutable - copy values
const headerSettings: { [name: string]: string | string[]; } = {};

for (const key of request.headers.keys()) {
headerSettings[key] = request.headers.getAll(key);
}

if (token && !(request.url.indexOf("viacep") != -1)) {
headerSettings['Authorization'] = token;
}
//headerSettings['Content-Type'] = 'application/json';
const newHeader = new HttpHeaders(headerSettings);

changedRequest = request.clone({
headers: newHeader
});

//console.log('Request', changedRequest);
return next.handle(changedRequest).pipe(catchError(err => {
this._authService.deuErro = true;
let mensagem: string = 'Ocorreu um erro desconhecido ao tentar processar a operação!'
switch (err.status){
case 400: if (err instanceof HttpErrorResponse && err.error instanceof Blob && err.error.type === "application/json") {
mensagem = "Não existem dados para serem gerados. Erro: " + err.status;
} else {
mensagem = err.error.message;
this._loadingController.dismiss();
}
break;

case 401: if (err.error.message === "Unauthorized"){
if (this._authService.userLogged.value.user) {
mensagem = 'Sua sessão foi expirada. Por gentileza, logue novamente! Erro: ' + err.status;
this._router.navigate(['auth/login']);
}else{
mensagem = mensagem + ' Erro: ' + err.status;
}
}
break;

case 500: if (err.error.message === "INVALID_CREDENTIALS") {
mensagem = 'Usuario ou senha incorretos. Digite novamente para realizar o login'
}else{
mensagem = mensagem + ' Erro: ' + err.status;
}
break;
default: mensagem = mensagem + ' (' + err.status + ')' + ' - ' + err.error.message
break;
}
this.exibir(mensagem)
return [];
}))
}

public exibir(msg) {
this._authService.open(msg); //This is the method that it tries to call
}
}
AuthService.ts
    import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable, BehaviorSubject } from 'rxjs';
import { map } from 'rxjs/operators';
import { Resolve, RouterStateSnapshot, ActivatedRouteSnapshot, Router } from '@angular/router';
import { ToastController, MenuController, AlertController, NavController } from '@ionic/angular';
import { environment } from 'src/environments/environment';
import { Storage } from '@ionic/storage';
import { promise } from 'protractor';
const API_STORAGE_KEY = 'spinopsstoragekey';

@Injectable({
providedIn: 'root'
})
export class AuthService implements Resolve<any>{

public userLogged: BehaviorSubject<any> = new BehaviorSubject({ imagem: null
, user: null
, nrCarteirinha: null
, listaBanners: null });
public token: string;
public users: BehaviorSubject<any[]> = new BehaviorSubject([]);
public deuErro: boolean = false;
public fl_comunicado: BehaviorSubject<boolean> = new BehaviorSubject(null);

constructor(
private _http: HttpClient,
private toastController: ToastController,
private _storage: Storage,
private _navController: NavController,
public _menuController: MenuController,
public _router: Router,
public alertController: AlertController,
) {
if (JSON.parse(localStorage.getItem('currentToken'))) {
const currentUser = JSON.parse(localStorage.getItem('currentUser'));
const currentToken = JSON.parse(localStorage.getItem('currentToken'));
const currentNrCarteirinha = JSON.parse(localStorage.getItem('currentUserLogin'));
const currentUserImage = JSON.parse(localStorage.getItem('currentUserImage'));
const currentListaBanner = JSON.parse(localStorage.getItem('currentListaBanner'));

this.token = currentUser && currentToken;

this.userLogged.next({
user: currentUser,
imagem: currentUserImage,
carteirinha: currentNrCarteirinha,
listaBanners: currentListaBanner
});
}
}

private URL = `${environment.apiUrl}/login`;
private User_URL = `${environment.apiUrl}/usuario`;

resolve(
route: ActivatedRouteSnapshot,
state: RouterStateSnapshot
): Observable<any> | Promise<any> | any {

}

login(dados: any, acessoRapido: boolean = false): Observable<any> {
let logon = dados;
if (acessoRapido){
logon = { ds_login: dados.dsLogin, ds_senha: dados.dsSenha, fl_salvar: dados.fl_salvar }
}

return this._http.post<any>(`${this.URL}`, logon)
.pipe(map(async user => {
const toast = await this.toastController.create({
message: 'Login realizado com sucesso.',
duration: 2000
});

if (user && user.token) {
localStorage.setItem('currentToken', JSON.stringify(user.token));
localStorage.setItem('currentUser', JSON.stringify(user.nomeUsuario));
localStorage.setItem('currentUserLogin', JSON.stringify(user.dsLogin));
localStorage.setItem('currentUserIdSegurado', JSON.stringify(user.idSegurado));
localStorage.setItem('currentUserImage', JSON.stringify(user.imagem));
localStorage.setItem('currentListaBanner', JSON.stringify(user.listaBanners));

this.userLogged.next({
user: user.nomeUsuario,
imagem: user.imagem,
carteirinha: user.dsLogin,
listaBanners: user.listaBanners
});

await this.setUserLogged(user);
await toast.present();
}

return user;
}));
}

logout(): void {
localStorage.removeItem('currentToken');
localStorage.removeItem('currentUser');
localStorage.removeItem('currentUserLogin');
localStorage.removeItem('currentUserIdSegurado');
localStorage.removeItem('currentUserImage');
localStorage.removeItem('currentListaBanner');

this._navController.navigateBack(['auth/login']).then(() => {
this._menuController.enable(false);
this.editUserLogged(null)
});
}

cadastrarConta(dados: any): Observable<any> {
this.deuErro = false
return this._http.post(`${environment.apiUrl}/beneficiario/novo`, dados);
}

alterarSenha(dados: any): Observable<any> {
this.deuErro = false
return this._http.put(`${environment.apiUrl}/beneficiario/alterar-senha`, dados);
}

public getUserRemember(): Promise<any> {
return this._storage.get(`${API_STORAGE_KEY}-lembrarUsuarios`);
}

public async setUserRemember(user): Promise<any> {
return this._storage.set(`${API_STORAGE_KEY}-lembrarUsuarios`, user);
}

public getUsersLogged(): Promise<any> {
return this._storage.get(`${API_STORAGE_KEY}-usuarioAutenticado`);
}

public setUserLogged(data: any) {
if (data) {
let users = [];
users.push(data);
return this._storage.set(`${API_STORAGE_KEY}-usuarioAutenticado`, users);
}
}

public editUserLogged(data: any) {
if (data.length > 0) {
return this._storage.set(`${API_STORAGE_KEY}-usuarioAutenticado`, data);
} else {
return this._storage.set(`${API_STORAGE_KEY}-usuarioAutenticado`, []);
}
}


async open(message, duration = 4000) {
const toast = await this.toastController.create({ message: `${message}`, duration: duration });
toast.present();
}

possuiComunicado() {
this._http.get(`${environment.apiUrl}/comunicado/possui`).subscribe((resolve: any) => {
this.fl_comunicado.next(resolve);
});
}

getComunicados() {
return this._http.get(`${environment.apiUrl}/comunicado/listar`);
}

setComunicado(nr_seq) {
return this._http.post(`${environment.apiUrl}/comunicado/${nr_seq}/ler`, {});
}
carregaImagem() {
const currentUserId = JSON.parse(localStorage.getItem('currentUserId'));
return this._http.get(`${this.User_URL}/carrega-imagem/${currentUserId}`, {
responseType: 'blob' as 'json'
});
}

getUserAvatar() {
return new Promise((resolve, reject) => {

this.carregaImagem().subscribe((res: any) => {

const file = new Blob([res], {
type: res.type
});

if (file.size !== 0) {
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = e => resolve(reader.result);
} else {
resolve('assets/avatars/profile.jpg');
}

}, reject);
});
}

}

The error
有人有什么想法吗?

最佳答案

这是 known issue由 HttpInterceptor 和 HttpClient 的循环依赖引起。
解释HttpClient依赖于所有 HttpInterceptors .AuthService依赖于 HttpClient .
在 HttpInterceptor 中注入(inject) AuthService 将创建一个无限循环。

HttpInterceptor -> AuthService -> HttpClient -> HttpInterceptor -> ∞
根据您的 Angular 版本,您将得到一个循环依赖错误,或者根本没有错误导致相关的注入(inject)服务为 undefined ,并且您的代码将默默地失败。
即使它应该是 fixed 自 Angular 5.2.3 以来,我最近在 Ionic 项目中也遇到了完全相同的问题。该修复可能允许 HttpClient 直接注入(inject) HttpInterceptor,但在通过服务注入(inject)时可能不起作用。
解决方案
注入(inject) Injector在拦截器构造函数而不是 AuthService 中,然后使用注入(inject)器手动检索服务。我不知道为什么,但你必须在这里使用某种延迟,否则 AuthService 可能仍然未定义。 platform.ready()setTimeout会做。
我还使用了 ready$ ReplaySubject确保在使用之前加载 AuthService。
...
import {Injectable, Injector} from '@angular/core';
import {AuthService} from '../services/auth.service';
import {Platform} from '@ionic/angular';
...

@Injectable()
export class Interceptor implements HttpInterceptor {

private ready$ = new ReplaySubject<void>(1);
private authService: AuthService;

constructor(private platform: Platform, private injector: Injector ) {
this.platform.ready().then(() => {
this.authService = this.injector.get(AuthService);
this.ready$.next();
});
}

get ready$(): Observable<void> {
return this.ready$.asObservable();
}

intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return this.ready$.pipe(
first(),
switchMapTo(next.handle(req)),
catchError((error: HttpErrorResponse) => {
...
return throwError(error);
})
);
}
...
}
这应该有效,如果您需要进一步的帮助,请告诉我。

关于angular - 我的拦截器上未定义构造函数变量(Angular 8),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65845155/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com