从 MongoDB 而不是 Angular2 中的模拟数据获取数据时,搜索管道失败
Search Pipe fails when getting data from MongoDB rather than Mock Data in Angular2
今天,我试图从使用存储在 const
中的模拟数据切换到使用存储在本地 MongoDB
中的相同数据,但出现错误:
Uncaught (in promise): Error: Error in ./FoodListComponent class FoodListComponent - inline template:2:30 caused by: Cannot read property 'filter' of undefined TypeError: Cannot read property 'filter' of undefined
at SearchPipe.transform (search.pipe.ts:15)
错误发生是因为我的 *ngFor
@ inline template:2:30
上的搜索管道
<div *ngFor="let food of foods | searchPipe: 'mySearchTerm'">
错误消息对我来说特别奇怪,因为服务返回的是 Observable
,而不是 Promise
。
如果我删除该搜索管道,则一切正常,但我没有搜索功能。就好像模板在数据到达之前正在编译一样。 我该如何纠正?
食物-list.component.ts
import { Component, OnInit, OnDestroy } from '@angular/core';
import { Food } from '../../../interfaces/diet/food'
import { FoodsService } from '../../../services/foods/foods.service';
@Component({
selector: 'food-list',
templateUrl: './food-list.component.html',
styleUrls: ['./food-list.component.scss'],
providers: [ WorkingDataService, FoodsService ]
})
export class FoodListComponent implements OnInit, OnDestroy {
foods: Food[];
constructor ( private _foodsService: FoodsService) { }
ngOnInit(): void {
// this._foodsService.getFoods().subscribe(foods => this.foods = foods); // this worked fine
this._foodsService.getMongoFoods().subscribe(foods => this.foods = foods);
}
}
foods.service.ts
import { Injectable } from '@angular/core';
import { Food } from '../../interfaces/diet/food'
import { FOODS } from './mock-foods';
import { Observable } from "rxjs/Rx";
import { Http, Response } from '@angular/http';
@Injectable()
export class FoodsService {
baseURL: string;
constructor(private http: Http) {
this.baseURL = 'http://localhost:3000/'
}
getFoods(): Observable<Food[]> { // this worked with my search pipe
return Observable.of(FOODS); // I'm returning an observable to a const
}
getMongoFoods(): Observable<Food[]>{
return this.http.get(this.baseURL + 'api/foods')
.map(this.extractData)
.catch(this.handleError);
}
// ... standard response and error handling functions
}
search.pipe.ts
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({
name: 'searchPipe',
pure: false
})
export class SearchPipe implements PipeTransform {
transform(foods: any[], mySearchTerm: string): any[] {
let mySearchTerm = mySearchTerm.toUpperCase();
foods = foods.filter(food => { // The failure hits here because foods isn't defined yet
// my filter logic
});
}
}
直到您的 observable 自行解析,您的 foods 数组未定义为以 in food-list.component.ts 开头,因为您尚未初始化它:
foods: Food[];
如果你把它改成
foods: Food[] = [];
它应该工作。
或者,您可以在管道的开头检查未定义,例如:
if (!foods) return foods;
今天,我试图从使用存储在 const
中的模拟数据切换到使用存储在本地 MongoDB
中的相同数据,但出现错误:
Uncaught (in promise): Error: Error in ./FoodListComponent class FoodListComponent - inline template:2:30 caused by: Cannot read property 'filter' of undefined TypeError: Cannot read property 'filter' of undefined at SearchPipe.transform (search.pipe.ts:15)
错误发生是因为我的 *ngFor
@ inline template:2:30
<div *ngFor="let food of foods | searchPipe: 'mySearchTerm'">
错误消息对我来说特别奇怪,因为服务返回的是 Observable
,而不是 Promise
。
如果我删除该搜索管道,则一切正常,但我没有搜索功能。就好像模板在数据到达之前正在编译一样。 我该如何纠正?
食物-list.component.ts
import { Component, OnInit, OnDestroy } from '@angular/core';
import { Food } from '../../../interfaces/diet/food'
import { FoodsService } from '../../../services/foods/foods.service';
@Component({
selector: 'food-list',
templateUrl: './food-list.component.html',
styleUrls: ['./food-list.component.scss'],
providers: [ WorkingDataService, FoodsService ]
})
export class FoodListComponent implements OnInit, OnDestroy {
foods: Food[];
constructor ( private _foodsService: FoodsService) { }
ngOnInit(): void {
// this._foodsService.getFoods().subscribe(foods => this.foods = foods); // this worked fine
this._foodsService.getMongoFoods().subscribe(foods => this.foods = foods);
}
}
foods.service.ts
import { Injectable } from '@angular/core';
import { Food } from '../../interfaces/diet/food'
import { FOODS } from './mock-foods';
import { Observable } from "rxjs/Rx";
import { Http, Response } from '@angular/http';
@Injectable()
export class FoodsService {
baseURL: string;
constructor(private http: Http) {
this.baseURL = 'http://localhost:3000/'
}
getFoods(): Observable<Food[]> { // this worked with my search pipe
return Observable.of(FOODS); // I'm returning an observable to a const
}
getMongoFoods(): Observable<Food[]>{
return this.http.get(this.baseURL + 'api/foods')
.map(this.extractData)
.catch(this.handleError);
}
// ... standard response and error handling functions
}
search.pipe.ts
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({
name: 'searchPipe',
pure: false
})
export class SearchPipe implements PipeTransform {
transform(foods: any[], mySearchTerm: string): any[] {
let mySearchTerm = mySearchTerm.toUpperCase();
foods = foods.filter(food => { // The failure hits here because foods isn't defined yet
// my filter logic
});
}
}
直到您的 observable 自行解析,您的 foods 数组未定义为以 in food-list.component.ts 开头,因为您尚未初始化它:
foods: Food[];
如果你把它改成
foods: Food[] = [];
它应该工作。
或者,您可以在管道的开头检查未定义,例如:
if (!foods) return foods;