Angular 2 search feature failing to accurately filter results based on user-provided input string

How can I implement a filter for the users list based on specific details? The users list is populated from form data and displayed in the view using *ngFor.

I attempted to create a custom pipe to filter the userslist based on a search query inputted in a search box. However, when I enter a search string, the userslist in the view becomes empty.

// 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 angular/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 submitted 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 dropdown list values on initialization
  ngOnInit() {
    // form controls validation specified 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>

Answer №1

To update your transform, follow the steps below:

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

In an HTML context,

<li class="list-item" *ngFor="let item of itemsList | filter:courseStatus:'chosenCourse'">

The existing implementation of the filter function is incorrect.

Take a look at this Plunker example!!

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

Utilizing Angular 8's Reactive Form to Transform Checkbox Event Output into a String Format

My form is reactive and includes a field called Status, which can have the values 'A' or 'I': this.form = this.formBuilder.group({ result_info: this.formBuilder.array([ this.getResultcontrols()]), stat ...

Transforming data objects into simplified interfaces using Typescript

Issue Explanation Current data: { "field1": "value", "field2": 3, "field3": true, "extraField": "toRemove" } An interface is defined as follows: export interface MyInterface { field1: string; field2: number; field3: boolean; } Objective ...

Advantages of incorporating types through imports versus relying solely on declaration files in Typescript

We are currently in the process of switching from plain JavaScript to TypeScript. One aspect that I personally find frustrating is the need to import types. In my opinion, importing types serves no real purpose other than cluttering up the import section ...

What is the reason for the successful compilation of "require" and the failure of "import"?

Currently getting familiar with TypeScript/JavaScript, as well as Node.js, I am in the process of creating a basic script to run via command line. After adding the dependency archiver and inserting import archiver from 'archiver';to my script, I ...

What is the method to utilize attributes from one schema/class in a separate schema?

Consider the scenario presented below: Base.ts import Realm from 'realm'; export type BaseId = Realm.BSON.ObjectId; export interface BaseEntity { id?: BaseId; createdAt: string; updatedAt: string; syncDetails: SyncDetails; } e ...

The attribute 'y' is not found within the data type 'number'

Currently working on a project using Vue.js, Quasar, and TypeScript. However, encountering errors that state the following: Property 'y' does not exist on type 'number | { x: number[]; y: number[]; }'. Property 'y' does not ...

What is the best approach to enhance a class definition that lacks types from DefinitelyTyped?

Recently, I came across the need to utilize the setNetworkConditions method from the Driver instance in selenium-webdriver. This method can be found in the source code here. Surprisingly, when checking DefinitelyTyped for TypeScript types, I discovered th ...

The seamless integration of NestJs, Angular, and Cognito for a streamlined user

Implementing the Authentication and Authorization flows can be tricky without concrete examples. While NestJs doc provides a good example for JWT tokens, I still struggle to establish the correct flow. Here is my current approach to solving the authorizat ...

Decide on the chosen option within the select tag

Is there a way to pre-select an option in a combobox and have the ability to change the selection using TypeScript? I only have two options: "yes" or "no", and I would like to determine which one is selected by default. EDIT : This combobox is for allow ...

Using the BrowserAnimationModule with the HTMLCanvasElement

I am facing an issue while integrating Angular Material Dialog with my component that includes an HTMLCanvas element for drawing. It seems like the BrowserAnimationModule, which is imported in app.module.ts and used by Material Dialog, is causing a delay i ...

Navigating the return types of Array shifts in Typescript 2.0 with rigorous null checks

In my project using Typescript 2.0 with strict null checks, I am working with an array: private _timers: ITimer[] and have the following if statement: if(this._timers.length > 0){ this._timers.shift().stop(); } However, I encounter a compile error ...

Restricting the data type of a parameter in a TypeScript function based on another parameter's value

interface INavigation { children: string[]; initial: string; } function navigation({ children, initial }: INavigation) { return null } I'm currently working on a function similar to the one above. My goal is to find a way to restrict the initi ...

What is the best way to close ngx-simple-modal in angular7 when clicking outside of the modal component?

Can anyone help me with closing the modal in my angular7 app when the user clicks outside of the modal component? I have been using the ngx-simple-modal plugin, and I tried implementing the following code: this.SimpleModalService.addModal(LinkPopupCompone ...

What is the best way to dynamically change the main content based on the sidebar option chosen in a React application?

https://i.sstatic.net/fkIyh.png Currently, I am in the process of creating the layout for the page similar to the image provided. When a user selects option A from the sidebar, my goal is to display the corresponding content on the same page without navig ...

Issues arise when Typescript fails to convert an image URL into a base64 encoded string

My current challenge involves converting an image to base 64 format using its URL. This is the method I am currently using: convertToBase64(img) { var canvas = document.createElement("canvas"); canvas.width = img.width; canvas.height = img.he ...

Retrieving data and parameter data simultaneously from the ActivatedRoute

I am currently utilizing Angular and have a webpage where I need to send data to another page. Transmit an array of selected values Generate multiple records (associating with a model) this.activatedRoute.data.subscribe(({ model] }) => { setTim ...

Issue ( Uncaught TypeError: Trying to access a property of undefined ('data') even though it has been properly defined

One of my custom hooks, useFetch, is designed to handle API data and return it as a state. useFetch: import { useState, useEffect } from "react"; import { fetchDataFromApi } from "./api"; const useFetch = (endpoint) => { const [d ...

Having difficulty transferring information from the component to the service

I am having trouble passing a parameter to a function that is defined in a service. No matter what I try, the parameter always ends up being undefined. login.component.ts import { Component, OnInit } from '@angular/core'; import { Authenticati ...

Utilizing React Redux and TypeScript to link a component with OwnProps in the ReactRedux template project of .NET Core 2.0

You can find the source code here. After some troubleshooting, I managed to get my code 99% working. However, despite everything running smoothly after compilation, I encountered a warning about the count property being missing when using it in a parent c ...

Tips for showcasing the chosen radio button onclick in Angular within ngFor

script.js //imports are all set ngOnInit() { this.list = { 'eatList': [{ 'type': 'Fruits', 'color': ['Red', 'White', 'Black'], ...