Vishal
Vishal

Reputation: 6368

filter pipe always logs undefined

I am trying to filter data in a table using input. For that I have created a custom pipe named textFilter as follows:

import {Pipe, PipeTransform} from '@angular/core';
import { Person } from '../Models/person';

@Pipe({ 
    name: 'textFilter',
    pure: false
}) 
export class TextFilterPipe implements PipeTransform {
    transform(people: Person[], filter: string): any {
        if (!people || !filter) {
            return people;
        }
        people.forEach(person => {
           console.log(person.firstName); //<-- this line logs undefined
        });
        console.log(filter);
        return people.filter(person => person.firstName.indexOf(filter) !== -1);
    } 
}

Then I am using it like this:

<div class="container" >
  <input type="text" [(ngModel)]="query" (keyup)="0" />
  <table>
    <thead>
      <tr>
        <td>First Name</td>
        <td>Last Name</td>
      </tr>
    </thead>
    <tbody>
      <tr *ngFor="let person of people | textFilter : query">
        <td>{{person.firstName}}</td>
        <td>{{person.lastName}}</td>
      </tr>
    </tbody>
  </table>
</div>      

Here is my Component.ts:

import { Component, OnInit } from '@angular/core';
import { Person } from '../../Models/person';

@Component({
  selector: 'app-auto-complete',
  templateUrl: './auto-complete.component.html',
  styleUrls: ['./auto-complete.component.css']

})
export class AutoCompleteComponent implements OnInit{

    constructor() {}

    query: string;
    people: Person[];

    ngOnInit() {
        this.query = '';
        this.people  = [
            new Person ("Shane", "Watson", "Australia"),
            new Person ("David", "Warner", "Australia"),
            new Person ("Ricky", "Ponting", "Australia"),
            new Person ("Adam", "Gilchrist", "Australia"),
            new Person ("Andrew", "Symonds", "Australia"),
            new Person ("Sachin", "Tendulkar", "India"),
            new Person ("Rahul", "Dravid", "India"),
            new Person ("Virender", "Sehwag", "India"),
            new Person ("Mahendra", "Dhoni", "India"),
            new Person ("Virat", "Kohli", "India"),
            new Person ("Gautam", "Gambhir", "India")
        ];
    }
}

Here is my person class:

export class Person {
    firstName: string;
    lastName: string;
    country: string;

    constructor(firstName: string, lastName: string, country: string) {}
}

Why person.firstName is always undefined inside TextFilterPipe?

Update:

If I log person instead of person.firstName then I get

Person {}

printed on console

Upvotes: 0

Views: 54

Answers (1)

snorkpete
snorkpete

Reputation: 14564

export class Person {
    firstName: string;
    lastName: string;
    country: string;

    constructor(firstName: string, lastName: string, country: string) {}
}

If the above is the definition of your Person class, then that's your problem - in your constructor, you're receiving 3 string values, but you're not doing anything with them. You need to assign them to your properties.

So, you need to do:

constructor(firstName: string, lastName: string, country: string) {
  this.firstName = firstName;
  this.lastName = lastName;
  this.country = country;
}

Or preferably:

constructor(public firstName: string, public lastName: string, public country: string) {}

which is a Typescript shortcut that does the same thing. Note that I had to put an access modifier on the parameter names to get the automatic assignment to work. You can use public or private, but you must use one.

Upvotes: 1

Related Questions