【发布时间】:2020-04-07 17:50:36
【问题描述】:
我正在使用 Angular 9 + 通用。运行ng serve 时没有错误,然后我使用npm run build:ssr 构建应用程序并尝试使用节点运行:node dist/app/server/main.js 并在终端中收到以下错误:
Node Express 服务器监听 http://localhost:4000 TypeError: You 在预期流的地方提供了“未定义”。您可以提供一个 可观察、承诺、数组或可迭代。 在 subscribeTo (C:\Users\andri\OneDrive\Desktop\devfox\autorent\ng-videocms\dist\autorent\server\main.js:1:2547459) 在 subscribeToResult (C:\Users\andri\OneDrive\Desktop\devfox\autorent\ng-videocms\dist\autorent\server\main.js:1:2775326) 在 CatchSubscriber.error (C:\Users\andri\OneDrive\Desktop\devfox\autorent\ng-videocms\dist\autorent\server\main.js:1:1997435) 在 Observable_Observable._trySubscribe (C:\Users\andri\OneDrive\Desktop\devfox\autorent\ng-videocms\dist\autorent\server\main.js:1:1952954) 在 Observable_Observable.subscribe (C:\Users\andri\OneDrive\Desktop\devfox\autorent\ng-videocms\dist\autorent\server\main.js:1:1952574) 在 CatchOperator.call (C:\Users\andri\OneDrive\Desktop\devfox\autorent\ng-videocms\dist\autorent\server\main.js:1:1996823) 在 Observable_Observable.subscribe (C:\Users\andri\OneDrive\Desktop\devfox\autorent\ng-videocms\dist\autorent\server\main.js:1:1952428) 在 _task (C:\Users\andri\OneDrive\Desktop\devfox\autorent\ng-videocms\dist\autorent\server\main.js:1:1751796) 在 Observable_Observable.Observable.a.observer [as _subscribe] (C:\Users\andri\OneDrive\Desktop\devfox\autorent\ng-videocms\dist\autorent\server\main.js:1:1752141) 在 Observable_Observable._trySubscribe (C:\Users\andri\OneDrive\Desktop\devfox\autorent\ng-videocms\dist\autorent\server\main.js:1:1952792)
正如我所探索的,我的应用程序在启动时执行了 2 次 api 调用:
app.component.ts:
ngOnInit(){
get1();
get2();
}
get1() {
const loc = this.locationService.getPickupLocations().subscribe((data: Location[]) => {
this.pickupLocations = data;
this.formGroup.get(LocationFields.pickup).setValue(data[0].getId());
this.pickupLocationsList = this.pickupLocations.map((data): ISelectOption => {
return {
label: data.getName(),
value: data.getId(),
};
});
},
(error)=> {
console.log(error)
},
() => {
this.subs.add(loc);
this.pickupDateChange(this.formGroup.get(this.LocationFields.pickupDate).value);
});
}
get2() {
const drop = this.locationService.getDropOffLocations().subscribe((data: Location[]) => {
this.dropoffLocations = data;
this.formGroup.get(LocationFields.dropoff).setValue(data[1].getId());
this.dropoffLocationsList = this.dropoffLocations.map((data): ISelectOption => {
return {
label: data.getName(),
value: data.getId(),
};
});
},(error)=> {
console.log(error)
},
() => {
this.subs.add(drop);
});
}
LocationService.ts:
static locationsEndpoint = 'public/locations/rental';
getPickupLocations(): Observable<Location[]> {
const reqHeader = new HttpHeaders({ 'Content-Type': 'application/json', 'No-Auth': 'True' });
return this.http.get(`${LocationsService.locationsEndpoint}/pickup`, { headers: reqHeader }).pipe(
map((data: ILocationResponse) => this.hydrateCollectionData(data, LocationsHydrator))
);
}
getDropOffLocations(): Observable<Location[]> {
const reqHeader = new HttpHeaders({ 'Content-Type': 'application/json', 'No-Auth': 'True' });
return this.http.get(`${LocationsService.locationsEndpoint}/dropoff`, { headers: reqHeader }).pipe(
map((data: ILocationResponse) => this.hydrateCollectionData(data, LocationsHydrator))
);
}
和拦截器:
private static BASE_URL = environment.apiUrl;
readonly HEADER_AUTHORIZATION = 'Authorization';
readonly HEADER_ACCEPT = 'Accept';
readonly HEADER_CONTENT_TYPE = 'Content-Type';
readonly ACCEPT_LANGUAGE = 'Accept-Language';
constructor(
private authService: AuthService,
private localeService: LocaleService
) { }
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
if (req.headers.get('skip')) {
return next.handle(req);
}
if (req.url.startsWith('./assets')) {
return next.handle(req);
}
req = req.clone({
url: this._prefixUrl(req.url)
});
req = req.clone({
headers: req.headers.set(this.HEADER_ACCEPT, 'application/json')
});
req = req.clone({
headers: req.headers.set(this.HEADER_CONTENT_TYPE, 'application/json')
});
req = req.clone({
headers: req.headers.set(this.ACCEPT_LANGUAGE, this.localeService.getLocale())
});
// Set token if exists
const token = this.authService.getToken();
if (token) {
req = req.clone({
headers: req.headers.set(this.HEADER_AUTHORIZATION, `Bearer ${token}`)
});
}
return next.handle(req).pipe(
catchError((httpErrorResponse: HttpErrorResponse) => {
if(httpErrorResponse.error !== undefined){
const customError: ApiErrors = {
name: httpErrorResponse.error.name,
message: httpErrorResponse.error.message,
errors: httpErrorResponse.error.errors
};
return throwError(customError);
}
})
);
}
private _prefixUrl(path: string): string {
if (path.indexOf('/') === 0) {
path = path.substr(1, path.length - 1);
}
return `${Interceptor.BASE_URL}/${path}`;
}
我试过没有这些电话,试着评论其中一个。
当我禁用这些调用(评论它们)时,应用程序工作正常。
当我稍后给他们打电话时,在我评论他们之后,(点击),应用程序工作正常。
当我禁用拦截器时,它可以工作(所以问题出在它们身上,要改变什么??)
如何解决?为什么会这样?
【问题讨论】:
标签: javascript node.js angular typescript rxjs