Snowman08
Snowman08

Reputation: 425

Search/Filter in Angular application will not work

Question I would like to implement a search feature in my fetchemployee.component and I'm unable to get it working, any help would be greatly appreciated.

I keep getting the following error in web console and my search filter isn't working

ERROR TypeError: "it.toLowerCase is not a function"

Here is my filter.pipe.ts

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

@Pipe({
   name: 'filter'
})

export class FilterPipe implements PipeTransform {
   transform(items: any[], term: string): any[] {
       if (!items) return [];
       if (!term) return items;

       term = term.toLowerCase();

       return items.filter(it => {
           return it.toLowerCase().includes(term);
       });
   }
}

Here is my fetchemployee.component.ts

import { Component, Inject } from '@angular/core';

import { Http, Headers } from '@angular/http';

import { Router, ActivatedRoute } from '@angular/router';

import { EmployeeService } from '../../services/empservice.service'

@Component({

   selector: 'fetchemployee',

   templateUrl: './fetchemployee.component.html',

   styleUrls: ['./fetchemployee.component.css']

})

export class FetchEmployeeComponent {

   public empList: EmployeeData[];

   constructor(public http: Http, private router: Router, private
employeeService: EmployeeService) {

       this.getEmployees();

   }

   getEmployees() {

       this.employeeService.getEmployees().subscribe(

           data => this.empList = data

       )

   }

   delete(employeeID) {

       var ans = confirm(`Are you shoure you want to delete this deduction
for: ${employeeID}`);

       if (ans) {

           this.employeeService.deleteEmployee(employeeID).subscribe
((data) => {

               this.getEmployees();

           }, error => console.error(error))

       }

   }
   term: string = "";

}

interface EmployeeData {

   id: number;

   name: string;

   empno: string;

   purtype: string;

   bp: string;

   amount: number;
}

Here is my fetchemployee.component.html

<h1>Employee Deduction</h1>

<p *ngIf="!empList"><em>Loading...</em></p>

<p>

   <a class="btn btn-primary" [routerLink]="['/register-employee']">Create
New</a>

</p>
<input type="text" [(ngModel)]="term">

<div class="wrapper">
   <div class="table" *ngIf="empList">
       <div class="row header">
           <div class="cell">
               Employee Number
           </div>
           <div class="cell">
               Name
           </div>
           <div class="cell">
               Pur. Type
           </div>
           <div class="cell">
               B/P
           </div>
           <div class="cell">
               Amount
           </div>
           <div class="cell">
               Edit
           </div>
           <div class="cell">
               Delete
           </div>
       </div>
       <div class="row" *ngFor="let emp of empList | filter: term">
           <div class="cell" data-title="Employee Number">
               {{ emp.empno }}
           </div>
           <div class="cell" data-title="Name">
               {{ emp.name }}
           </div>
           <div class="cell" data-title="Pur. Type">
               {{ emp.purtype }}
           </div>
           <div class="cell" data-title="B/P">
               {{ emp.bp }}
           </div>
           <div class="cell" data-title="Amount">
               ${{ emp.amount }}
           </div>
           <div class="cell" data-title="Amount">
               <a class="alt" [routerLink]="['/employee/edit/',
emp.id]"></a>
           </div>
           <div class="cell" data-title="Amount">
               <a class="btn-danger" [routerLink]="" (click)="delete
(emp.id)"></a>
           </div>
       </div>
   </div>
</div>

And here is my app.shared.module.ts

import { NgModule } from '@angular/core';
import { EmployeeService } from './services/empservice.service'
import { CommonModule } from '@angular/common';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { HttpModule } from '@angular/http';
import { RouterModule } from '@angular/router';

import { AppComponent } from './components/app/app.component';
import { NavMenuComponent } from './components/navmenu/navmenu.component';
import { HomeComponent } from './components/home/home.component';
import { FetchEmployeeComponent } from
'./components/fetchemployee/fetchemployee.component'
import { createemployee } from
'./components/addemployee/AddEmployee.component'
import { FilterPipe } from "./components/fetchemployee/filter.pipe"

@NgModule({
   declarations: [
       AppComponent,
       NavMenuComponent,
       HomeComponent,
       FetchEmployeeComponent,
       createemployee,
       FilterPipe
   ],
   imports: [
       CommonModule,
       HttpModule,
       FormsModule,
       ReactiveFormsModule,
       RouterModule.forRoot([
           { path: '', redirectTo: 'home', pathMatch: 'full' },
           { path: 'home', component: HomeComponent },
           { path: 'fetch-employee', component: FetchEmployeeComponent },
           { path: 'register-employee', component: createemployee },
           { path: 'employee/edit/:id', component: createemployee },
           { path: '**', redirectTo: 'home' }
       ])
   ],
   providers: [EmployeeService]
})
export class AppModuleShared {
}

Here is what my data looks like

[
   {
       "id": 8,
       "name": "Jeffery Brown",
       "empno": "80",
       "purtype": "TLS",
       "bp": "B",
       "amount": "24.00"
   },
   {
       "id": 9,
       "name": "Robert Blue",
       "empno": "101",
       "purtype": "UNI",
       "bp": "B",
       "amount": "9.32"
   },
]

Upvotes: 0

Views: 382

Answers (1)

Reza
Reza

Reputation: 19913

The issue is about the type of it which is EmployeeData

Since seems you are adding FilterPipe as general you can pass property name you want to filter based on as below

export class FilterPipe implements PipeTransform {
   transform(items: any[], prop: string, term: string): any[] {
       if (!items) return [];
       if (!term) return items;

       term = term.toLowerCase();

       return items.filter(it => {
           return it[prop].toLowerCase().includes(term);
       });
   }
}

and use it as

<div class="row" *ngFor="let emp of empList | filter:'name':term">

Upvotes: 1

Related Questions