如何拦截呼叫并动态回送JSON文件(无“导入”)

问题描述 投票:0回答:2

我有一个文件夹和json文件支架,用于模拟API的路径。当我运行npm run start:mock时,LocalMockInterceptor被置备,例如用本地获得<的http调用替换对host / A / B / C的调用。 JSON文件由单独的脚本生成,该脚本不在此处范围内。许多教程显示,我无法使用“导入”,因为我需要通用的解决方案,因为我模拟的API会随着时间的推移而发展(文件夹和文件的这种支架也会随之发展)。

/** * The idea is to only build this into the bundle if we specify so (e.g. on TeamCity, on your localhost), where you don't want to rely * on external resources for development * No conditionals in the code bundle! No configuration files or database dependency. */ import { HttpInterceptor, HttpResponse, HttpHandler, HttpRequest, HttpEvent, HttpClient, HttpHeaders } from '@angular/common/http'; import { Injectable, Injector } from '@angular/core'; import { Observable, of } from 'rxjs'; import { ErrorService } from './error.service'; const devAssetsFolder = 'assets'; @Injectable() export class LocalMockInterceptor implements HttpInterceptor { constructor( private errorService: ErrorService, private injector: Injector, private http: HttpClient ) {} intercept( request: HttpRequest<any>, next: HttpHandler ): Observable<HttpEvent<any>> { if (request.url.endsWith('.json')) return next.handle(request); console.log( ` >>> Mock Interceptor >>> ${request.url} has been intercepted` ); const path = `${devAssetsFolder}${request.url}.json`; var promise = this.getJSON(path).toPromise(); const jsonheaders = new HttpHeaders(); jsonheaders.set('Content-Type', 'application/json'); let json2; promise .then(json => { console.log(json); json2 = json; }) .catch(error => console.log(error)); Promise.all([promise]); console.log(json2); return of( new HttpResponse({ status: 200, body: json2, headers: jsonheaders }) ); } private getJSON(jsonPath: string): Observable<any> { return this.http.get(jsonPath); } }
    第一个条件是避免无限循环,因为我正在拦截器中发送HTTP请求
  • 基于URL获取JSON文件的路径是很自然的
  • 在我看来,我必须将JSON Observable转换为Promise,以便在将JSON重新包装到返回的Observable中之前可以等待它完成。但是,在调试时,似乎Promise.all没有等待承诺完成(json2在下一行中未定义),并且我最终向后发送了一个空的http正文...

      如何解决rxjs承诺?
  • 内部HTTP调用是我唯一的选择吗?
  • 有没有不依靠承诺的方法?您能想到一种更好的方法吗?
json angular mocking angular8 angular-http-interceptors
2个回答
1
投票
您是否尝试仅在拦截器中修改目标URL?您想要进行一个返回一些JSON的API调用,而不是调用一个动态API,而只想调用您的静态服务器,以便它可以返回预定义的JSON。

intercept( request: HttpRequest<any>, next: HttpHandler ): Observable<HttpEvent<any>> { const fakeUrl = `${devAssetsFolder}${request.url}.json`; const fakeRequest = request.clone({url: fakeUrl}); return next.handle(request); }


1
投票
intercept( request: HttpRequest<any>, next: HttpHandler ): Observable<HttpEvent<any>> { if (request.url.endsWith('.json')) return next.handle(request); console.log( ` >>> Mock Interceptor >>> ${request.url} has been intercepted` ); const path = `${devAssetsFolder}${request.url}.json`; return this.getJSON(path).pipe(map(result => { const jsonheaders = new HttpHeaders({ 'Content-Type': 'application/json' }); return new HttpResponse({ status: 200, body: result, headers: jsonheaders }); }), // you can also add catchError here ); }
在拦截方法中,您可以返回一个可观察值。因此,您的getJSON方法返回了一个可观察值,我们在管道中添加了一个map函数,该函数将结果映射到新的http响应。如果您的响应已经具有正确的标题,则您甚至都不需要管道和映射功能,只需执行此操作即可:

return this.getJSON(path); // it's an observable, so it's OK.

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.