2017-01-05 7 views
0

Сегодня я пытаюсь переключиться с использования mock-данных, хранящихся в const, на использование тех же данных, хранящихся на моем локальном MongoDB, но я получаю сообщение об ошибке:Search Pipe не удается получить данные от MongoDB, а не Mock Data в Angular2

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 
     }); 
    } 
} 

ответ

1

До самого вашего наблюдаемых решает, ваш массив продуктов питания не определен, чтобы начать с в пищевом list.component.ts, потому что вы не инициализируетесь его:

foods: Food[];

, если вы измените что foods: Food[] = []; он должен Работа.

В качестве альтернативы вы можете сделать чек на неопределенный в начале вашей трубы, что-то вроде:

if (!foods) return foods;