Search code examples
angulartypescriptecmascript-6angular-forms

search filter not filtering based on string input in angular 2


I want to filter the users list based on somedetail. The users list is generated from the data submitted in the form. and the users list is dispalyed in the view using *ngFor.

I want to filter the userslist based on the query string in the search input box. For that i created a custom pipe which takes the search box string and compares it with the usersList array.

But when i enter the search string the userslist in view goes blank.

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

    @Pipe({
      name: 'filter'
    })
    export class FilterPipe implements PipeTransform {

      transform(value: any, filterString: string, propName: string): any {
        if (value.length === 0) {
          return value;
        }
        const resultArr = [];
        for (const item of value) {
          if (item[propName] === filterString) {
            resultArr.push(item);
          }
        }
      }

    }

// app component.ts

import { Component, OnInit, Input, ViewChild } from '@angular/core';
import { DropDownService } from './services/drop-down.service';
import { IPersonModel } from './interface/person-model';
import { InputDataService } from './services/input-data.service';
// FormBuilder imported from anuglar/forms
import { FormGroup, FormBuilder, Validators } from '@angular/forms';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
  providers: [DropDownService, InputDataService]
})
export class AppComponent implements OnInit {
  courseForm: FormGroup;
  personDetail: IPersonModel;
  dropDownArr = [];
  selectedOption = null;
  personsList: IPersonModel[] = [];
  courseStat = '';


  constructor(public dropdown: DropDownService, public fieldData: InputDataService, private fb: FormBuilder) {
  }
  onSubmit(): void {
    // adds the user submited data to personDetail object
    this.personDetail.chosenCourse = this.selectedOption;
    this.personDetail.name = this.courseForm.value.username;
    this.personDetail.email = this.courseForm.value.email;
    this.personDetail.address = this.courseForm.value.address;
    this.personDetail.date = this.courseForm.value.date;
    this.fieldData.setPersonData({ ...this.personDetail });
    this.personsList.push({ ...this.personDetail });
    console.log({ ...this.personDetail });
    this.courseForm.reset();
    console.log(this.personsList);
    console.log(this.courseForm);
  }


  // resets the form on clicking the reset button
  resetForm(): void {
    this.courseForm.reset();
  }
  // sets the dropdownlist values on intialization
  ngOnInit() {
    // form controls validation specicified in the class for the Reactive Forms
    this.courseForm = this.fb.group({
      username: [null, [Validators.required, Validators.pattern(/^[a-z0-9_-]{3,16}$/)]],
      email: [null, [Validators.required, Validators.pattern('([a-zA-Z0-9_.-]+)@([a-zA-Z0-9_.-]+)\\.([a-zA-Z]{2,5})')]],
      address: [null, [Validators.required, Validators.minLength(10), Validators.maxLength(100)]],
      date: [null, [Validators.required]],
      select: [null, [Validators.required]]
    });
    this.dropDownArr = this.dropdown.getData();
    // this.personDetail = {
    //   name: '',
    //   email: '',
    //   address: '',
    //   chosenCourse: ''
    // };
    this.personDetail = this.fieldData.getPersonData();
    console.log(this.courseForm);
  }

}

// component Html
 <div class="panel panel-default">
    <div class="panel-heading">Registered users</div>
    <input type="text" [(ngModel)]='courseStat' placeholder="filter based on course">

    <!-- List group -->
    <ul class="list-group">
      <!-- pipes transforms the username's first word by capitalize it-->
      <li class="list-group-item" *ngFor="let person of personsList | filter:personsList:courseStat:'chosenCourse'">username:&nbsp;&nbsp;{{person.name | capitalize}} &nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;&nbsp; email:&nbsp;&nbsp;{{person.email}}
        &nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;&nbsp; DOB: &nbsp;&nbsp;{{person.date | date: 'd/M/y'}} &nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;&nbsp;Address:
        &nbsp;&nbsp;{{person.address}} &nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;&nbsp; Course Chosen: &nbsp;&nbsp;{{person.chosenCourse
        | uppercase}}</li>
    </ul>
  </div>

Solution

  • you update your transform like below,

    transform(value: any, filterString: string, propName: string): any {
       
        if (value.length === 0 || !filterString || !propName) {
          console.log(filterString);
          return value;
        }
       
        return value.filter(_person => {
          return _person[propName] === filterString;
        })
    }
    

    in HTML,

     <li class="list-group-item" *ngFor="let person of personsList | filter:courseStat:'chosenCourse'">
    

    The way you have written filter is incorrect.

    Check this Plunker!!