- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个名为拦截器的服务,它可以获取后端发送的所有错误响应。在这个服务上,我有一个名为 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
,并且您的代码将默默地失败。
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/
我正在尝试在项目中学习和添加 Angular 国际化。我只能理解 Angular 文档 (https://angular.io/guide/i18n-overview) 的编译时翻译。 我需要这样的东
在我的 Angular 应用程序中,基于登录用户,我想通过显示/隐藏不同的菜单项或允许/禁止某些路由来授予或限制功能。 目前成功登录后,我的 .NET Core API 会返回一个 JWT token
我是 Angular 的新手,目前我已经看过 angular.io 网站提供的一些示例。但是在component decorator在文档中的解释,它指出 Angular components are
这里是service employee-service.service.ts的代码 import { Injectable } from '@angular/core'; import { HttpC
我目前正在使用@angular/http URLSearchParams 类来检索 URL 参数。在 Angular 5 中,注意到这已被弃用,但我没有看到以我当前使用的方式替换 URLSearchP
我目前正在使用@angular/http URLSearchParams 类来检索 URL 参数。在 Angular 5 中,注意到这已被弃用,但我没有看到以我当前使用的方式替换 URLSearchP
如何正确安装 PUG/JADE 到 Angular 2 或更高版本 这样在工作和 AOT 和 JiT 的同时 工作单元和集成测试 并且在创建每个新组件时不会受到太多影响 最佳答案 我看到了很多解决方案
我的 Angular 12 应用程序中有一些通用组件,我计划将其创建为一个 Angular 库,以便其他应用程序也可以使用它。我们有一些应用程序在较低版本的 angular(例如 angular 8/
tl;dr; ng build 删除了包含我编译的自定义库的/dist 文件夹。这会使我项目代码中对该库的所有引用无效,从而导致 ng build 最终失败。我做错了什么? 我关注了documenta
我正在将一些“遗留”(非 typescript )js 库导入到我的 Angular SPA 中。 通常我只是从 cdn 添加一个负载到 index.html 就像: 在 Angular 分量中我只
我有这个 angular 应用程序,它基本上使用了库的概念。 我有 2 个名为 的库Lib1 和 lib2 根据他们所服务的微服务分组。 现在我将这些库导入主应用程序,即 应用1 事情一直到现在。 现
我在我的项目中启用了 angular Universal。我现在想完全删除它。我试图删除以下文件 /server.ts /webpack.server.config.js /src/tsconfig.
我已经有一个 AuthService 在登录时对用户进行身份验证,并且 AuthGuard 在未登录的情况下阻止访问。 某些页面我通过 UserProfile/Role 限制访问,但现在我需要阻止页面
我正在尝试使用 angular、TypeORM、SQLite 和其他组件作为 webpack 构建 Electron 应用程序。 我从在 GitHub 上找到的示例开始我的开发:https://git
我在从 Angular 8 更新到 9 并运行时遇到以下错误 ng 更新@angular/material: Package "@angular/flex-layout" has an incompa
我正在尝试使用 Angular 9,我想创建一个项目,然后创建一个库项目并开始向其中添加我想稍后在 GitHub 上发布的通用模块,并在我的本地使用这些库项目。 相关依赖如下: Angular CLI
我正在尝试使用 Angular 9,我想创建一个项目,然后创建一个库项目并开始向其中添加我想稍后在 GitHub 上发布的通用模块,并在我的本地使用这些库项目。 相关依赖如下: Angular CLI
我正在我的 h1 元素“之前”创建一个小的程式化三 Angular 形图案,但我无法正确地圆 Angular 。右上角没问题,但其他两个有剪裁问题。 这是输出以及形状的放大图像: 使用的代码如下: h
我有一个 Angular 元素,带有自定义标记名 - fancy-button。如何将 fancy-button 嵌入 Angular 应用程序? 我已经尝试了以下方法,但都没有用 - 在 index
我已将我的项目从 angular 5.2.9 升级到 angular 6.0.0-rc.5。 除了包路径中的几个快速 RxJS 修复外,一切看起来都不错。(此链接非常有用:Want to upgrad
我是一名优秀的程序员,十分优秀!