我有一个文件夹和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);
}
}
Promise.all
没有等待承诺完成(json2
在下一行中未定义),并且我最终向后发送了一个空的http正文... 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);
}
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.