Ionic4: the functionality of the searchbar results is not functioning correctly

I have integrated the ion-searchbar in my application to filter a list of customers based on their first name and/or last name. However, I am facing two major challenges:

Challenge 1: The search bar currently only matches either the first name OR the last name of a customer, but not both simultaneously. For instance, if a customer's name is Marshall Legend and I type in Marshall, the filter works fine. Similarly, typing in Legend also yields results. But when I enter Marshall Legend, no matches are found.

Challenge 2: Let me explain this with an example scenario. Initially, the search feature works correctly by displaying only customers with the name "Marshall" when searched for. However, as soon as a new customer from another client is added to the list, all customers are displayed regardless of the filter, even though "Marshall" is still present in the search bar.

I have been struggling with these issues for quite some time now and any assistance would be highly appreciated. Below is a snippet of my code:

My component code

export class Tab2Page implements OnInit {
  public searchTerm: string = "";
  public customerCollection: AngularFirestoreCollection<any>;
  public customers: any[];
  public unfilteredCustomers: any[];

  constructor(private afs: AngularFirestore, 
    public modalController: ModalController,
    private databaseService: DatabaseService) {}

  ngOnInit(){
    this.customerCollection = this.afs.collection('Customers');
    this.customerCollection.valueChanges().subscribe( val => {
      this.customers = val;
      this.unfilteredCustomers = val;
    });
  }

  /**
   * Search functionality 
   */
  public onSearchTerm() {
    if(/\S/.test(this.searchTerm)){
      this.customers = this.unfilteredCustomers.filter(customer => {
        return customer.lastName.toLowerCase().includes(this.searchTerm.toLowerCase())  
        || customer.firstName.toLowerCase().includes(this.searchTerm.toLowerCase());
      });
    } else {
      this.customers = this.unfilteredCustomers;
    }
  }

My template code

    <ion-item-sliding *ngFor="let customer of customers">
          <ion-item-options side="start">
            <ion-item-option (click)="viewCustomerDetails(customer)">Details</ion-item-option>
          </ion-item-options>
        <ion-item>
         <ion-label>
         <ion-icon name="person"></ion-icon> {{customer?.firstName}} 
           {{customer?.lastName}}
         </ion-label>
         </ion-item>
          <ion-item-options side="end">
            <ion-item-option color="danger" (click)="removeCustomer(customer)">Return</ion-item-option>
          </ion-item-options>
    </ion-item-sliding>

Answer №1

Solution 1

Here is a revised search logic:

  1. If the first name or last name is equal to "legend", return true
  2. If the first name or last name is equal to "marshall", return true
  3. If the first name or last name is equal to "marshall legend", return true

Due to the split between first and last names in Firestore properties, the third scenario will never occur. Try implementing this alternative approach instead:

  public onSearchTerm() {
    if (searchTerms.length < 1) {
      this.customers = this.unfilteredCustomers;
      return;
    }

    const searchTerms = this.searchTerm.split(' ').map(s => s.trim().toLowerCase());

    this.customers = this.unfilteredCustomers.filter(customer => {
      var firstName = customer.firstName.toLowerCase();
      var lastName = customer.lastName.toLowerCase();

      var results = searchTerms.filter(name => firstName.includes(name) || lastName.includes(name));

      return results.length > 0;
    });

  }

Solution 2

In your ngOnInit function, you are subscribed to changes in your customers collection. When changes occur, it overwrites the this.customers variable and causes all results to be displayed. Consider implementing the following modification:

  ngOnInit(){
    this.customerCollection = this.afs.collection('Customers');
    this.customerCollection.valueChanges().subscribe( val => {
      this.unfilteredCustomers = val;

      // If there is a search term, filter the results
      if (this.searchTerm.trim().length > 0) {
        this.onSearchTerm();
      } else {
        this.customers = val;   
      }
    });
  }

Answer №2

Here is an example of how you can utilize this:

public onSearchTerm() {
if(/\S/.test(this.searchTerm)){
  this.customers = this.unfilteredCustomers.filter(customer => {
    let fullname = customer.firstName+" "+customer.lastName
    return fullname.toLowerCase().includes(this.searchTerm.toLowerCase())  ;
  });
} else {
  this.customers = this.unfilteredCustomers;
}

}

The above code will only return either a matching first name or last name, not both

return customer.lastName.toLowerCase().includes(this.searchTerm.toLowerCase())  
    || customer.firstName.toLowerCase().includes(this.searchTerm.toLowerCase());

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Use include files to wrap content in a div tag

I have a webpage index.html with the following JavaScript scripts: <script type="text/javascript> $(document).ready(function() { $('a.link').click(function() {var url = $(this).attr('href'); $('#content'). ...

"Sorry, but there seems to be an issue with

My shop: { customers: [ { id: 12345, name: Customer A }, { id: 54321, name: Customer B } ] } I am attempting to modify the name attribute for Customer A. I am utilizi ...

error message indicating modal is not appearing

I am facing an issue with the twitter bootstrap modal not triggering properly. I have already included the necessary js and CSS files, but I am encountering two errors in the console. The errors are as follows: Uncaught TypeError: undefined is not a fun ...

What is the best way to pass data between sibling components using services?

I'm looking to connect a service to a component that can fetch data, share objects, and communicate with other components that are already linked to the database. I've established a service named DashService as follows: import { Injectable } fro ...

Convert a JavaScript variable to a TypeScript interface

In my JavaScript project, I am utilizing TypeScript and JSDOC for code validation against the TS compiler. When analyzing my code, the TS compiler identifies an error in the following snippet: interface IBox { idx: number; } interface IBoxes { ...

Using AJAX to transfer a variable from a range slider to a PHP query

I'm currently trying to pass a JavaScript variable from a range slider to a PHP query. The goal is to have the front-page of my Wordpress theme display all posts tagged with the value selected on the range slider without having to refresh the page. To ...

Selecting multiple rows using a datakey

Working on a project that utilizes the PrimeNg UI library has brought to light an issue with the datakey property in the table component. When examining the selection array, only one row is being selected even though the UI visually highlights all the rela ...

Is there a way to easily access the last element of an array in an Angular2 template without the need to iterate through the entire

I'm not trying to figure out how to access looping variables like i, first, last. Instead, my question is about how to retrieve and set variables as template variables. My current approach doesn't seem to be working... <div #lastElement="arr ...

Arrangement of populations within a component

Currently, I have the following parent component implemented. class IndecisionApp extends React.Component { render() { const options = ['Thing one', 'Thing two', 'Thing three'] return ( < ...

Creating an Angular template using the Teams Toolkit within Visual Studio Code

I'm looking to create a basic step-by-step form on Microsoft Teams using my existing Angular application. However, I've noticed that there are only React templates available in Visual Studio Code for building tabs in Teams. Do I have to use these ...

Retrieve information using an AJAX call

There is JSON data stored in a file that I need to read. The correct file data is printed to the console.log. What steps should I take to assign this data to variable x? Currently, when I execute the code, x ends up being undefined. function getData() { ...

Iterating through children of the target element using the .each() method in jQuery

Currently, I am looping through the elements and extracting the src attribute from the child element. This is the snippet of HTML code that I am working with: <noscript data-alt="super awesome"> <img src="http://farm9.staticflickr.com/8235/85 ...

Exploring the wonders of utilizing `instanceof` in TypeScript

Looking at this simple node+ts code: import * as express from "express"; function processRequest(app: express.Application) { if (!(app instanceof express.Application)) throw new TypeError(); // additional logic here... } When I check the code in VSC ...

Unable to function properly on Backbone.js, events have been rendered ineffective

I have recently created a view with the following code snippets: var app = app || {}; app.singleFlowerView = Backbone.View.extend({ tagName: 'article', className: 'flowerListItem', // specifies where to render the views templ ...

Utilize jQuery to compare JavaScript files between the cache and the application

When making changes to my JS files in the application, I find myself constantly having to clear my browser's cache to see those changes. To avoid this inconvenience, I tried using the following: <script type="text/javascript" src="js/main.js?cache ...

Using JavaScript to add a class when hovering over an element

I am trying to customize the ul inside one of my li elements in the nav by adding a class when hovered. However, I am encountering an issue where the menu disappears when I try to click on it after hovering over it. I want to achieve this functionality usi ...

What is the best way to find the product of each object in an array by the corresponding values in another array?

Searching for a solution to an issue I encountered while working on an assignment. The problem can be illustrated as follows: var arrOfObj = [{a:10 },{a:20},{a:30}, ......] var arrToMultiply = [2,4,6, .....] The expected result const result = [{a:10,resul ...

Having trouble accessing a custom factory within a directive in Angular using TypeScript

Having some trouble with my injected storageService. When trying to access it in the link function using this.storageService, I'm getting an undefined error. Any assistance on this issue would be greatly appreciated. module App.Directive { import ...

Require a Single Error Message When Two Fields Are Left Blank

I've been working on an asp.net contact form that includes fields for 'Tel No.' and 'Email'. I'm trying to set up one error message for when both of these fields are left blank upon form submission, but I just can't seem ...

Sending JSON data using Ajax with circular reference

The JSON structure I am working with is as follows: "node": { "id": "812de6d0-a754-11e7-a7d4-47a3233fb668", "name": "123", "type": "node", "children": [ { "id": "d517b899-d211-4896-8eeb-466268ddf2e3", "name" ...