1
votes

as I am in process of learning and understanding angular 2 I am facing this issue. I have a service that makes a http get request.

import { Injectable } from '@angular/core';
import { Http, Response, } from '@angular/http';
import { Observable } from 'rxjs/Rx'

import { LanguagesResponse } from '../shared/model/languages/languages-response';

@Injectable()
export class HttpLanguageService {

    constructor(private http: Http) { }

    getLanguages(): Observable<LanguagesResponse> {
        return this.http.get('http://192.168.99.100:8888/em-deployer/ws/languages?pretty=true&expand=true').map(this.extractData)
            .catch(this.handleError);
    }


    private extractData(res: Response) {
        let body = res.json();
        console.log(body);
        return body || {};
    }

    private handleError(error: any) {
        // In a real world app, we might use a remote logging infrastructure
        // We'd also dig deeper into the error to get a better message
        let errMsg = (error.message) ? error.message :
            error.status ? `${error.status} - ${error.statusText}` : 'Server error';
        console.error(errMsg); // log to console instead
        return Observable.throw(errMsg);
    }
}

I have a component which will be responsible to get the result of the service and put it in the template. (ngFor)

import { Language } from "../shared/model/languages/language";
import { HttpLanguageService } from '../http-services/http-language.service';
import { Component, OnInit } from '@angular/core';

@Component({
    selector: 'app-iate-quick-mode',
    templateUrl: './quick-mode.component.html',
})
export class QuickModeComponent implements OnInit {

    languages: Language[];
    errorMessage: string;
    sourceNonEuLanguages: boolean = true;
    targetNonEuLanguages: boolean = true;

    constructor(private httpLanguageService: HttpLanguageService) {
    }

    ngOnInit() {
        this.getLanguages();
        console.log(this.languages);
    }

    getLanguages() {
        this.httpLanguageService.getLanguages()
            .subscribe(
            (languages) => {
                this.languages = languages.items;
                console.log(this.languages);
            },
            error => this.errorMessage = <any>error,
        );
    }

}

A custom pipe that will return some results based on a boolean value to the returned array.

import { Pipe, PipeTransform } from '@angular/core';

@Pipe({
    name: 'languagesFilter'
})
export class LanguagesFilterPipe implements PipeTransform {

    transform(items: any[], arg: boolean): any {

        return items.filter(item => item.is_official == arg);
    }

}

And my template

  <div>
           <dl class="EU-languages">
                <dd class="language EU-lang"
                                *ngFor="let language of (languages | languagesFilter:true)">
                                <input type="radio"
                                    id="{{language.code}}" />
                                <label htmlFor="{{language.code}}"> {{language.code | uppercase}}</label>
                            </dd>
                        </dl>
     </div>

When I am not using the pipe everything works and I have all the array objects populated and shown in the template. When I am using the pipe I am getting the error below => caused by: Cannot read property 'filter' of undefined. I changed the array to a array with an initialized array and the pipe works. Any recommendations? What am I missing?

1

1 Answers

0
votes

It's cause the first time your pipe is called, there isn't a list/array yet..

Change your pipe like this:

import { Pipe, PipeTransform } from '@angular/core';

@Pipe({
    name: 'languagesFilter'
})
export class LanguagesFilterPipe implements PipeTransform {
    transform(items: any[], arg: boolean): any {
        if (!items || !items.length) return [];
        return items.filter(item => item && item.is_official == arg);
    }
}

You could initiate your local variable like this:

languages: Language[] = [];

.. but modified Pipe should help in any other "errors" too!