Angular 2 Pipe - Multipe Filters

Hello -

I'm working with pipes to filter a data set. I am new to Angular 2...so I am baby stepping my way into the full functionality I am trying to implement.

I'm working to add two separate filters...looking at two separate fields. I want to do them separately b/c the data set the filters will be applied to will be large....and response times for the second filter (which will be searching a name field) will be slower than response times for the 1st filter (which will be looking at an ID).

I've implemented the search functionality to look at two fields...which is great. However, I want it to not return anything unless something is entered into one of the search boxes. When i was working with just one filter for the ID field...i was able to do this using
if (!IDSearch) return null

Open in new window

. If  I did not have that specified...it caused problems when the user changed IDs. How do I add similar logic to when using the two search boxes?

Below is the code for my pipe component.


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

@Pipe({
  name: 'employeeSelection'
})
export class EmployeeSelectionPipe implements PipeTransform {


//CH Multiple Search Play
public transform(items: any[], IDSearch: string, nameSearch: string) {
    if (items && items.length){
            return items.filter(item =>{

                if (IDSearch && item.ID.toLowerCase().indexOf(IDSearch.toLowerCase()) === -1){
                    return false;
                }
                if (nameSearch && item.EmployeeName.toLowerCase().indexOf(nameSearch.toLowerCase()) === -1){
                    return false;
                }

                return true;
           })
        }
        else{
            return null;
        }
  
    }

  }

export const appPipes = [EmployeeSelectionPipe];

Open in new window

Cynthia HillLead ConsultantAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Julian HansenCommented:
I just need to understand are you passing your dataset through each filter

let a of items | filer1:Criteria1 | filter2:Criteria2

Open in new window

0
it_saigeDeveloperCommented:
Are you looking for something like this?
public transform(items: any[], IDSearch: string, nameSearch: string) {
    if (items && items.length) {
        return items.filter(item => {
            if (IDSearch && item.ID) {
                if (nameSearch && item.EmployeeName) {
                    return (item.ID.toLowerCase().indexOf(IDSearch.toLowerCase()) === -1) || (item.EmployeeName.toLowerCase().indexOf(nameSearch.toLowerCase()) === -1);
                } else {
                    return (item.ID.toLowerCase().indexOf(IDSearch.toLowerCase()) === -1);
                }
            } else if (nameSearch && item.EmployeeName) {
                return (item.EmployeeName.toLowerCase().indexOf(nameSearch.toLowerCase()) === -1);
            }
            return true;
        })
    } else {
        return null;
    }
}

Open in new window


-saige-
0
Cynthia HillLead ConsultantAuthor Commented:
Hey Julian - Yes...

I am passing the dataset through each filter in my HTML file.

  <ng-container *ngFor="let user of users | employeeSelection:attuidSearch: nameSearch">

Open in new window


Here is a slimmed down version of the HTML file. I have more fields in the official version...but this gives you an idea. You will also notice I am splitting different types of fields into separate tables (to give the output a more organized look on the screen and so its easier on make sense of the data since I will have a good number of fields to display).
<div >
  <!-- style="text-align:center" -->
  <h1>
    Employee Profile
    </h1>
</div>
<div>
  <!-- Search Text -->
  <div>
<h4>Enter ID</h4>  <input [(ngModel)]="IDSearch" />
<h4>Enter Employee Name</h4>  <input [(ngModel)]="nameSearch" />
    <hr>
   </div>
<!-- <hr> -->
  <h4>PERSONAL INFORMATION</h4>
  <table class="table">
      <!-- <caption><h3>PERSONAL INFORMATION</h3></caption> -->
  <ng-container *ngFor="let user of users | employeeSelection:IDSearch: nameSearch">
      <tr>
        <th>ID</th><td>{{user.ID}}</td>
        <th>Employee Name</th><td>{{user.EmployeeName}}</td>
      </tr>
    
      <tr>
        <th>Work Phone</th><td>{{user.Phone}}</td>
        <th>Cell Phone</th><td>{{user.CellPhone}}</td>
      </tr>
      <tr>
        <th>Email Address</th><td>{{user.eMailAddress}}</td>
        <th>Employee Status</th><td>{{user.EmployeeStatus}}</td>
      </tr>
            </ng-container>
</table>


  <h4>JOB INFORMATION</h4>
  <table class="table">
    <ng-container *ngFor="let user of users | employeeSelection:IDSearch: nameSearch">
        <tr>
          <th>Job Key</th><td>{{user.JobKey}}</td>
          <th>Job Description</th><td>{{user.JobDescription}}</td>
        </tr>
      
      </ng-container>
</table>
</div>

Open in new window

0
Determine the Perfect Price for Your IT Services

Do you wonder if your IT business is truly profitable or if you should raise your prices? Learn how to calculate your overhead burden with our free interactive tool and use it to determine the right price for your IT services. Download your free eBook now!

Cynthia HillLead ConsultantAuthor Commented:
Hey IT Saige - Thanks for your response. That does not seem to be doing what I need.

I do not want any records from the dataset to load until something is entered into one of the search filters. When I apply the code you suggested...when I refresh the screen (or remove values from the filters) all records return by default.  

I do not want any records until something is entered.

When I was working with just one filter...
if (!IDSearch) return null

Open in new window

...did the trick...but not sure how to do something similar while having it look at both fields.
0
Julian HansenCommented:
This works for me
Comonent
import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'EE Angular Sample 5 (Angular 4.3)';
  users = [
    {
        "firstName": "Clark",
        "lastName": "Kent",
        "job": "Reporter",
        "id": 20
    },
    {
        "firstName": "Bruce",
        "lastName": "Wayne",
        "job": "Business Owner",
        "id": 30
    },
    {
        "firstName": "Peter",
        "lastName": "Parker",
        "job": "Photographer",
        "id": 40
    },
    {
        "firstName": "Tony",
        "lastName": "Stark",
        "job": "Business Owner",
        "id": 25
    }
]
}

Open in new window

Template
Id <input [(ngModel)]="id" />
Lastname <input [(ngModel)]="lastName" />

<table class="table">
<ng-container *ngFor="let user of users | search:id:lastName">
      <tr>
        <th>First Name</th><td>{{user.firstName}}</td>
        <th>Last Name</th><td>{{user.lastName}}</td>
      </tr>
      <tr>
        <th>Job</th><td>{{user.job}}</td>
        <th>ID</th><td>{{user.id}}</td>
      </tr>
    </ng-container>
</table>
</div>

Open in new window

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

@Pipe({
  name: 'search'
})
export class SearchPipe implements PipeTransform {
  public transform(items: any[], id: string, lastName:string) {
    return items.filter(item => {
      if (id && item.id.toString().indexOf(id) > -1) return true;
      if (lastName && item.lastName.toLowerCase().indexOf(lastName.toLowerCase()) > -1) return true;
    });
  }
}

export const appPipes = [SearchPipe];

Open in new window


Working sample here
0
Julian HansenCommented:
The above code will only display records when you enter something in one of the filters - however, bear in mind that the entire dataset will still have been downloaded.

Is this how you want it to work?
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Cynthia HillLead ConsultantAuthor Commented:
Hey Julian - that does what I want for now. I have at least 2 other items for the functionality I want to work in...but because I am learning...I need to take things in chunks so I have a better chance of following the solutions.

Thanks!
0
Julian HansenCommented:
You are welcome.
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Web Development

From novice to tech pro — start learning today.