0

I have a pipe for searching an array of users for id or name. It works fine. If I write the user id number it will find it. If I write the name it will find only if the names are written sequentially

But I want to search for example for firstname and lastname and get the user with firstname secondname thirdname lastname

I know that I have to split the querystring ( splitted = querystring.split(' ') and search for both the names but I don't know how.

I do not want a static of 2 terms search but a dynamic of 2, 3,etc... the ones that the user wants.

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

@Pipe({
  name: 'querystring'
})
@Injectable()
export class PesquisaPipe implements PipeTransform {
  transform(users: any[], querystring: any): any[] {
   if ( querystring=== undefined) {
     return users;
   }
   return users.filter(z => {
     const userID = z.userID.toString().includes(querystring.toLocaleLowerCase());
     const userName = z.userName.toLocaleLowerCase().includes(querystring.toLocaleLowerCase());
     return( userID + userName);
   });
  }

1 Answer 1

1

Welcome to stackoverflow!

First, it is a bad idea to use a pipe for filtering or sorting. The documentation warns about this here: https://angular.io/guide/pipes#appendix-no-filterpipe-or-orderbypipe

Instead, do the filtering in the code.

Second, there are several ways to handle filtering of multiple cases, I have a blog post that covers it here: https://blogs.msmvps.com/deborahk/filtering-in-angular/

In general, you can filter on multiple criteria using an OR || as follows:

performFilter(filterBy: string): IProduct[] {
    filterBy = filterBy.toLocaleLowerCase();
    return this.products.filter((product: IProduct) =>
          product.productName.toLocaleLowerCase().indexOf(filterBy) !== -1 || 
          product.description.toLocaleLowerCase().indexOf(filterBy) !== -1);
}

The above code files a specified string if found in the productName OR description.

Or you can filter on any object property as follows:

performFilter(filterBy: string): IProduct[] {
    filterBy = filterBy.toLocaleLowerCase();
    return this.products.filter((product: IProduct) => 
        Object.keys(product).some(prop => {
            let value = product[prop];
            if (typeof value === "string") {
                value = value.toLocaleLowerCase();
            } 
            return value.toString().indexOf(filterBy) !== -1;
        })    
    );
}

The above code searches all properties of the object for a specific provided string.

The linked blog post provides additional options.

Applying this to what I think you are asking:

performFilter(filterBy: string): User[] {
    filterBy = filterBy.toLocaleLowerCase();
    return this.users.filter((user: User) =>
          user.name.toLocaleLowerCase().indexOf(filterBy) !== -1 || 
          user.userId.toLocaleLowerCase().indexOf(filterBy) !== -1 ||
          user.userName.toLocaleLowerCase().indexOf(filterBy) !== -1);
}
Sign up to request clarification or add additional context in comments.

4 Comments

Thanks for the answer, im using it for searching and displaying on a table in "realtime". My question refers to a string that as a space and should be treated as 2 diferent strings to search with an AND operator
If you are referring to a name, what about people with names like "Robert De Nero" or "Jamie Smith Gerwin"? or "Mary Jo Fowley". How do you determine which parts are the "first name" vs which parts are the "last name"?
I don't, the name is in a string, i just want to search the string for names, the code that i posted above do that but sequentially
What do you mean by sequentially? I'll update my answer with my understanding of what you are asking for.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.