Guide on integrating a search filter into a current list using Angular 2

Here is the HTML code I am working with:

<ul style="list-style: none;" class="list-unstyled" xmlns:list-style-type="http://www.w3.org/1999/xhtml">
  <li *ngFor="let t of acquirer_response | keys">
    <ul class="list-unstyled"  class="list-group" >
      <li *ngFor="let b of t.value | keys ">
        <ul class="list-unstyled" style ="list-style-type: none" >
          <strong (click)="t.isCollapsedContent =!t.isCollapsedContent" (click)=" toggleSign(sign)" ><span class="glyphicon glyphicon-{{sign}}-sign"></span> {{b.key}}</strong>
          <div *ngIf="t.isCollapsedContent">
            <li *ngFor="let c of b.value | keys ">
              <div *ngIf="c.key == 'request'"  style="border: none">
                <ul  style="list-style: none;" class="list-unstyled"   class="list-group-item list-group-item-info" style="border: none">
                  <strong  class="list-group-item list-group-item-info"  (click)="c.value.isCollapsedContent =!c.value.isCollapsedContent">
                    <span class="glyphicon glyphicon-{{sign}}-sign"  (click)=" toggleSign(sign)"  ></span>{{c.key}}
                  </strong>
                  <li  class="list-unstyled" *ngIf="c.value.isCollapsedContent" class="list-group-item list-group-item-info">
                    <table id="user" class="table table-bordered table-striped table-condensed" style = "overflow: hidden;" width="100%" >
                      <thead>
                      <tr>
                       <th>Field</th>
                        <th>Length</th>
                        <th>Value</th>
                      </tr>
                      </thead>
                      <tr *ngFor="let d of c.value | keys" class="list-group-item-info">

                        <td nowrap=" ">{{d.value.Field}}</td>
                        <td>{{d.value.length}}</td>
                        <td style="word-wrap: break-word;min-width: 160px;max-width: 160px; white-space:normal">{{d.value.value}}</td>
                      </tr>
                    </table>
                  </li>
                </ul>
              </div>
              <div *ngIf="c.key == 'response'">
                <ul style="list-style: none;" class="list-unstyled"   class="list-group-item list-group-item-info" style="border: none">
                  <strong  class="list-group-item list-group-item-info"  (click)="c.value.isCollapsedContent =!c.value.isCollapsedContent"  (click)=" toggleSign(sign)" >
                    <span class="glyphicon glyphicon-{{sign}}-sign" ></span>{{c.key}}
                  </strong>
                  <li  class="list-unstyled" *ngIf="c.value.isCollapsedContent" class="list-group-item list-group-item-info">
                    <table datatable="ng" class="table table-bordered table-striped table-condensed">
                      <thead>
                      <tr>
                        <th>Field</th>
                        <th>Length</th>
                        <th>Value</th>
                      </tr>
                      </thead>
                      <tr *ngFor="let d of c.value | keys" class="list-group-item-info">
                        <td>{{d.value.Field}}</td>
                        <td>{{d.value.length}}</td>
                        <td>{{d.value.value}}</td>
                      </tr>
                    </table>
                  </li>
                </ul>
              </div>
            </li>
          </div>
        </ul>
      </li>
    </ul>
  </li>
</ul>

This is how my component looks like:

import { NgModule,Input } from '@angular/core';
import { Component ,OnInit} from '@angular/core';
import {AcquirerService} from '../services/acquirer.service'
import { Pipe, PipeTransform } from '@angular/core';
import {Collapse} from './collapse.component';



@Component({

  selector : 'acquirer-message',
  templateUrl: '../templates/acquirer.component.html',
//  template : '<parent-view [txn] = "acquirer_response"></parent-view>' ,

  providers :[AcquirerService]
})

@NgModule({
  declarations: [Collapse]
})
export class AcquirerComponent implements  OnInit {

  public isCollapsedContent:boolean = false;

  acquirer_response : any[];

  constructor(private _acquirerService:AcquirerService) {

  }

  ngOnInit() {

    this._acquirerService.getAcquirer()
      .subscribe(resAcquirerData => {

        this.acquirer_response = resAcquirerData.transactions

        console.log(this.acquirer_response);
        // console.log(this.acquirer_response.transactions);
    });


  }

  sign = 'plus';  // or minus if you want that first

  toggleSign(value :string) {
    this.sign = value;
    if(this.sign == 'plus') {
      this.sign = 'minus';
    } else {
      this.sign = 'plus';
    }
  }


}

@Pipe({name: 'keys'})
export class KeysPipe implements PipeTransform {

  transform(value) {
    let keys:any = [];
    for (let key in value) {

      keys.push( {key: key, value: value[key]} );
      console.log("value of key :"+key ,"value :"+ value);
    }
    return keys;

  }

}

The result should be a nice tree view like below:

 Transaction ref : 321916010424
     request
     response
 Transaction ref : 000463000046
     request
     response

I now want to add a search/filter functionality. For example, if I type 321916010424 in the search box, it should display only the matching record as shown below:

Transaction ref : 321916010424
         request
         response

I know I need to use pipes for this, but I'm unsure of the implementation. Should I utilize the existing pipe in the component? If so, how can I achieve this since I'm new to Angular 2 development? Any help would be greatly appreciated.

For reference, here is an example of my JSON data structure:

{
    "transactions": [{
        "Transaction ref : 321916010424": {
            "request": [{
                "Field": "DE-000",
                "length": "004",
                "value": "0100"
            }, {
                "Field": "DE-001",
                "length": "016",
                "value": "11110010 ... truncated ... "
            }],
            "response": [{
                "Field": "DE-000",
                "length": "004",
                "value": "0110"
            }, {
                "Field": "DE-001",
                "length": "008",
                "value": "00110010 ... truncated ... "
            }, {
                "Field": "DE-003",
                "length": "006",
                "value": "003000"
            }]
        }
    }, {
        "Transaction ref : 000463000046": {
            "request": [{
                "Field": "DE-000",
                "length": "004",
                "value": "0100"
            }, {
                "Field": "DE-001",
                "length": "016",
                "value": "11110010 ... truncated ... "
            }],
            "response": [{
                "Field": "DE-000",
                "length": "004",
                "value": "0110"
            }, {
                "Field": "DE-001",
                "length": "008",
                "value": "00110010 ... truncated ... "
            }, {
                "Field": "DE-063",
                "length": "009",
                "value": "AMXHZGWJ7"
            }]
        }
    }]
}

Answer №1

My implementation strategy is as follows:

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

@Pipe({name: 'Searchkeys'})
export class AcquirerTxnSearchPipe implements PipeTransform {

  transform(items, args:string) {

    let ans:any = [];
    let result:any = [];
    let kvalue:any = [];

    if (args !== undefined) {
       console.log("Value of arguments in the loop condition-->" + args)

      for (let key in items) {

        kvalue = items[key];

        for (let a in kvalue) {
          if (a.substr(18).startsWith(args)) {
            ans.push({key: key, value: items[key]});
            console.log("Matched transaction ==>" + ans)
            result = ans;
          }
        }
      }
    }

    else {
      console.log("Value of arguments not undefined--->" + args);
      for (let key in items) {
        console.log("Value of key --->"+ key)
        ans.push({key: key, value: items[key]);
        result = ans;
      }
    }
    return result;

  }

}

Another pipe that loads all the details:

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

@Pipe({name: 'keys'})
export class AcquirerTxnPipe implements PipeTransform {

  transform(value) {
    let keys:any = [];
    for (let key in value) {
      keys.push( {key: key, value: value[key]} );
      console.log("Value of key :"+key ,"value :"+ value);
    }
    return keys;
  }

}

In the HTML file, I called the search pipe to filter the records based on user input and then display the data using the normal pipe. The code snippet is as below:

<div id="search-component">
  <h4>Transaction Search</h4>
  <input #searchBox id="search-box" [(ngModel)]="queryString"  placeholder="Type here to search" />
  <p>&nbsp;</p>

  <div>
    <ul style="list-style: none;" class="list-unstyled" xmlns:list-style-type="http://www.w3.org/1999/xhtml">
      <li *ngFor="let t of searchacquirer_response | Searchkeys :queryString ">
        <ul class="list-unstyled"  class="list-group" >
          <li *ngFor="let b of t.value | keys" style="list-style-type: none;">
            <ul class="list-unstyled" style ="list-style-type: none" >
              <strong (click)="t.isCollapsedContent =!t.isCollapsedContent" (click)=" toggleSign(sign)" ><span class="glyphicon glyphicon-{{sign}}-sign"></span> {{b.key}}</strong>
              <div *ngIf="t.isCollapsedContent">
                <li *ngFor="let c of b.value | keys ">
                  <div *ngIf="c.key == 'request'"  style="border: none">
                    <ul  style="list-style: none;" class="list-unstyled"   class="list-group-item list-group-item-info" style="border: none">
                      <strong  class="list-group-item list-group-item-info"  (click)="c.value.isCollapsedContent =!c.value.isCollapsedContent">
                        <span class="glyphicon glyphicon-{{sign}}-sign"  (click)=" toggleSign(sign)"  ></span>{{c.key}}
                      </strong>
                      <li  class="list-unstyled" *ngIf="c.value.isCollapsedContent" class="list-group-item list-group-item-info">
                        <table id="user" class="table table-bordered table-striped table-condensed" style = "overflow: hidden;" width="100%" >
                          <thead>
                          <tr>
                            <th>Field</th>
                            <th>Length</th>
                            <th>Value</th>
                          </tr>
                          </thead>
                          <tr *ngFor="let d of c.value | keys" class="list-group-item-info">
                            <td nowrap=" ">{{d.value.Field}}</td>
                            <td>{{d.value.length}}</td>
                            <td style="word-wrap: break-word;min-width: 160px;max-width: 160px; white-space:normal">{{d.value.value}}</td>
                          </tr>
                        </table>
                      </li>
                    </ul>
                  </div>
                  <div *ngIf="c.key == 'response'">
                    <ul style="list-style: none;" class="list-unstyled"   class="list-group-item list-group-item-info" style="border: none">
                      <strong  class="list-group-item list-group-item-info"  (click)="c.value.isCollapsedContent =!c.value.isCollapsedContent"  (click)=" toggleSign(sign)" >
                        <span class="glyphicon glyphicon-{{sign}}-sign" ></span>{{c.key}}
                      </strong>
                      <li  class="list-unstyled" *ngIf="c.value.isCollapsedContent" class="list-group-item list-group-item-info">
                        <table datatable="ng" class="table table-bordered table-striped table-condensed">
                          <thead>
                          <tr>
                            <th>Field</th>
                            <th>Length</th>
                            <th>Value</th>
                          </tr>
                          </thead>
                          <tr *ngFor="let d of c.value | keys" class="list-group-item-info">
                            <td nowrap=" ">{{d.value.Field}}</td>
                            <td>{{d.value.length}}</td>
                            <td style="word-wrap: break-word;min-width: 160px;max-width: 160px; white-space:normal">{{d.value.value}}</td>
                          </tr>
                        </table>
                      </li>
                    </ul>
                  </div>
                </li>
              </div>
            </ul>
          </li>
        </ul>
      </li>
    </ul>
  </div>
</div>

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

Transitioning create-react-app from JavaScript to Typescript

A few months ago, I began a React project using create-react-app and now I am interested in transitioning the project from JavaScript to TypeScript. I discovered that there is an option to create a React app with TypeScript by using the flag: --scripts-v ...

The logic behind combining elements from two arrays in JavaScript/TypeScript

Explanation of two different array formats const arr1 = [ { "elementName": "one" }, { "elementName": "two" } ] const arr2 = [ { "type": "RPT_PROPERTY_DEMOGRP", "values": [ { "label": "HH" }, { " ...

Troubleshooting Angular 6: Issues with Route Guards not functioning as expected

Striving to enhance frontend security by restricting access to specific IDs. The goal is to redirect anyone trying to access routes other than /login/:id to a page-not-found error message if not already logged in, but encountering some issues. Below are t ...

Enhancing Password Strength Validation with Formik and Yup in a React Application

I am new to React and currently working on a signup page where I need to validate the password field using Regex. While utilizing Formik and Yup for validations, I encountered an issue where it shows the error that the property being called by the length ...

Issue: Unable to locate a change supporting element '[object Object]' of the type 'object - Angular 7'

An angular service has been created for the specified purpose: CheckTicket(barcode, codEspec, diaHoraEspec):Observable<Ticket[]>{ //read ticket return this.http.get<Ticket[]>(`${this.checkticket_url}${barcode}?token=${this.token}&a ...

What is the best way to incorporate delete buttons for clearing the entire state and removing specific states generated by the .map function?

I attempted to initialize the array to clear all elements inside of it, however, it was not successful. clearAll(){ this.setState({ posts: [] }) } componentDidMount() { axios.get('https://jsonplaceholder.typicode.com/posts') ...

Ways to access an observable's value without causing a new emit event

Is there a way to retrieve the value of an observable without causing it to emit again? I need this value for an ngClass expression. I attempted to use the tap operator within the pipe to access the values in switchMap, but the value is not being logged. ...

Struggling to incorporate a pause decorator into my application, I encountered difficulties while trying to understand a related issue

I am currently working with a service file that contains the following: export class MockDataService { data:[] = []; getAll(): Observable<any[]> { return of(this.data); } } To introduce a delay to my mocks, I decided to use a @pause() decora ...

Error: JSON unexpected token ' at position 2 - Solution for fixing this issue

Encountering a recurring JSON error where the user input from a textbox is being passed in JSON for assigning class level permissions in a parse server. var cc = "role:" + user; var jsonParam = "{ 'classLevelPermissions' : { ...

Extending an External Object with Custom Properties in TypeScript

When working with an external library, I often find myself needing to add new properties to passed-in parameters. Instead of using (<any>conv.data) due to the compiler error Object is of type 'unknown', I'm curious if there's a mo ...

What is the process for defining a state using React Native and TypeScript?

Recently, I've embarked on my journey with React Native and decided to incorporate TypeScript into my development process. As I attempted to set my state, an error popped up that reads as follows: An issue arose while trying to assign the argument &a ...

Why is the removal of this type assertion in TypeScript causing an issue?

Why is TypeScript refusing to compile this code snippet? interface TaggedProduct { tag: string; } interface Product { tag?: string; } const tagProduct = (product: Product): TaggedProduct => { const tag: string = "anything"; pro ...

Tips for extracting data from an Angular object using the *ngFor directive

https://i.stack.imgur.com/ai7g1.png The JSON structure displayed in the image above is what I am working with. My goal is to extract the value associated with the key name. This is the approach I have taken so far: <span *ngFor="let outlet of pr ...

What is the process for displaying the attributes of a custom object in Typescript?

I need help returning an array of prop: value pairs for a custom object using the myObject[stringProp] syntax. However, I keep encountering this error message: TS7053: Element implicitly has an 'any' type because expression of type 'str ...

Issue: The keyword in React/React-Native is returning a boolean value instead of the expected element object

I've recently delved into learning and coding with React, and I'm encountering a bug that I need help fixing. The issue lies within my application screen where I have two checkboxes that should function like radio buttons. This means that when on ...

Warning: The TypeScript version in use may not support all features. The current language level is set to XX in Visual Studio 2019

After installing VS 2019, I noticed that Microsoft.TypeScript.MSBuild 4.2.3 was added. On my Windows 10 OS, I also installed it using NPM in the following way: However, upon opening VS 2019, I encountered the warning below: TypeScript 3.4 feature Curre ...

What is the process of attaching data to a mat form field in Angular?

How can I show the data from an http request on a form field in Angular? I want the user to be able to edit the data and submit it. The email, firstname, etc. should display in the input fields. When the edit button is clicked, I want the form field value ...

Error in Typescript occurring with a custom typography element

I recently developed a simple typography component for my React project and it's causing a Typescript error that's puzzling me a bit. Typography Component Code import clsx from 'clsx'; const sizeVariants = { h1: 'h1', ...

How come I am unable to fetch classes and enums from a namespace?

When using Typescript with pg-promise, I am facing an issue where I can't import the classes and enums as I normally would. Typically, when working with a library, I import a type, use it, and everything functions properly. However, in the snippet bel ...

The useNavigate function cannot be utilized in a custom hook created with createBrowserRouter

Presently, I've developed a custom hook specifically for handling login and logout functionalities export function useUser() { const { token, setToken, user, setUser } = useContext(AuthContext) const navigate = useNavigate() const { ...