简体   繁体   English

HttpInterceptor 和 In memory 数据服务 Angular 7

[英]HttpInterceptor and In memory data service Angular 7

I have been using a dummy auth for an app I am working on.我一直在为我正在开发的应用程序使用虚拟身份验证。 So I have implemented this successfully using a dummy local user.所以我已经使用虚拟本地用户成功实现了这一点。

Unfortunately I have hit a brick wall when it comes to trying to get this to work with the in memory data service.不幸的是,当我试图让它与 in memory 数据服务一起工作时,我遇到了障碍。 My users array is coming back undefined and a unable to change error to string in the console log.我的用户数组返回未定义并且无法将错误更改为控制台日志中的字符串。 Below is the fake back end using the interceptor.下面是使用拦截器的假后端。

import { Injectable, OnInit } from '@angular/core';
import { HttpRequest, HttpResponse, HttpHandler, HttpEvent, HttpInterceptor, HTTP_INTERCEPTORS, HttpClient } from '@angular/common/http';
import { Observable, of, throwError } from 'rxjs';

import { User } from '@/data/models/property/user';
import { UserService } from '@/_services/user.service';

@Injectable()
export class FakeBackendInterceptor implements HttpInterceptor, OnInit {

  users: User[];

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

  ngOnInit() {
    this.getAll();
  }
  private getAll(): void {
    this.userService.getAll()
      .subscribe(data => this.users = data);
  }

  intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    // authenticate
    if (request.url.endsWith('/users/authenticate') && request.method === 'POST') {
    // find if any user matches login credentials
      const filteredUsers = this.users.filter(user => {
        if (user.email === request.body.email && user.password === request.body.password) {
        return user;
        }
      });

    if (filteredUsers) {
      // if login details are valid return 200 OK with user details and fake jwt token
      const user = filteredUsers[0];
      const body = {
        id: user.id,
        email: user.email,
        firstName: user.firstName,
        lastName: user.lastName,
        studentNo: user.studentNo,
        isStaff: user.isStaff,
        token: 'fake-jwt-token'
      };

    return of(new HttpResponse({ status: 200, body: body }));
      } else {
        // else return 400 bad request
        return throwError({ error: { message: 'Email or password is incorrect' } });
      }
    }
    return next.handle(request);

  }
}

and next is my user service.接下来是我的用户服务。

 import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable, of } from 'rxjs';
import { catchError, map, tap } from 'rxjs/operators';

import { User } from '../data/models/property/user';

@Injectable({ providedIn: 'root' })
export class UserService {
  constructor(private http: HttpClient) { }

  getAll(): Observable<User[]> {
    return this.http.get<User[]>('api/users')
      .pipe(
        catchError(this.handleError('getAll', []))
      );
  }

  getById(id: number) {
    return this.http.get(`/users/${id}`);
  }

  register(user: User) {
    return this.http.post(`/users/register`, user);
  }

  update(user: User) {
    return this.http.put(`/users/${user.id}`, user);
  }

  delete(id: number) {
    return this.http.delete(`/users/${id}`);
  }

  private handleError<T>(operation = 'operation', result ?: T) {
    return (error: any): Observable<T> => {

      // TODO: send the error to remote logging infrastructure
      console.error(error.name); // log to console instead

      // Let the app keep running by returning an empty result.
      return of(result as T);
    };
  }
}

I suspect this is something I have missed or unsure on.我怀疑这是我错过或不确定的事情。 Any help gratefully received.任何帮助感激不尽。

EDIT: When debugging I am getting a RangeError: Maximum call stack size exceeded编辑:调试时出现 RangeError: Maximum call stack size exceeded

return the error through hadlers catch 通过hadlers catch返回错误

intercept(request: HttpRequest < any > , next: HttpHandler): Observable < HttpEvent < any >> {
    // authenticate
    if (request.url.endsWith('/users/authenticate') && request.method === 'POST') {
        // find if any user matches login credentials
        const filteredUsers = this.users.filter(user => {
            if (user.email === request.body.email && user.password === request.body.password) {
                return user;
            }
        });

        if (filteredUsers) {
            // if login details are valid return 200 OK with user details and fake jwt token
            const user = filteredUsers[0];
            const body = {
                id: user.id,
                email: user.email,
                firstName: user.firstName,
                lastName: user.lastName,
                studentNo: user.studentNo,
                isStaff: user.isStaff,
                token: 'fake-jwt-token'
            };

            let response = of (new HttpResponse({
                status: 200,
                body: body
            }));
            return handle(response);
        } else {
            // else return 400 bad request
            next.handle().catch((response: any) => {
                // ....
                // Do messaging and error handling here
                return throwError({
                    error: {
                        message: 'Email or password is incorrect'
                    }
                });
            });
        }
    }
}

This is old, but I think you don't understand what an HTTP interceptor is supposed to do.这是旧的,但我认为你不明白 HTTP 拦截器应该做什么。 You shouldn't call the getAll() service method in your interceptor, and definitely not in the ngOnInit() , which has no place there anyway, interceptors are not components.您不应该在拦截器中调用getAll()服务方法,绝对不应该在ngOnInit()中调用,无论如何那里都没有地方,拦截器不是组件。 The only thing your interceptor needs to do is assign the response of the faked back-end request to some local data that you can store and export in some local file as a simple JSON object.你的拦截器唯一需要做的就是将伪造的后端请求的响应分配给一些本地数据,你可以将这些数据存储并导出到一些本地文件中,作为一个简单的 JSON object。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM