Using multiple pipes in Angular 4 with Typescript to manipulate values

I've developed a custom pipe called 'filterBy' and I want to implement it in my application. Most of it is functioning well, but I am facing challenges when trying to use this pipe for multiple properties. Allow me to elaborate on what I am struggling with.

Custom Pipe Definition

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

@Pipe({
  name: 'filterBy',
  pure: false
})

@Injectable()
export class FilterBy implements PipeTransform {
  transform( array: Array<any>, filterField: string, filterValue: string, filterField2: string, filterValue2: any): Array<any> {
    if (!array) return [];
    return array.filter(item => item[filterField] === filterValue);
  }
}

products.component.html

<div class="col-sm-1 lessmargins" *ngFor="let product of products | filterBy: 'condition': 'new'"

Although the above snippet works fine, each product has properties such as condition, prices, etc. For instance, I would like to display products with 'condition' : 'new' and 'condition' : 'used' simultaneously, but I am unsure how to achieve this. I attempted the following approach: products.component.html

*ngFor="let product of products | filterBy: {'condition': 'new'} && {'condition' : 'used'}"

Unfortunately, it did not yield the desired result. Is there an issue with my pipe implementation? Could someone provide clarification or guidance?

Answer №1

To filter based on multiple properties, create an array of filters containing the properties you want to filter on and pass it to the pipe. Iterate through the array of properties within the pipe to ensure all match. Here's an example:

Create a Filter class for your filters:

export class Filter {
    public name: string;
    public value: any;
}

Then, add new filters to an array and use this array in your pipe:

<div class="col-sm-12" *ngFor="let product of products | filterBy: filters">
</div>

Next, loop through the array of filters inside your pipe:

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

@Pipe({
  name: 'filterBy',
  pure: false,
})
export class FilterBy implements PipeTransform {
  transform( array: Array<any>, filters: Array<Filter>): Array<any> {
    if (!array) return [];
    if (!filters) return array;

    return array.filter(item => matchAll(item, filters));
  }
}

function matchAll(item: any, filters: Array<Filter>): boolean {
  let valid = true;
  for (const filter of filters) {
    if (!hasKey(item, filter.name)
      || item[filter.name] !== filter.value) {
      valid = false;
      break;
    }
  }

  return valid;
}

function hasKey(item: any, keyName: string): boolean {
  return Object.keys(item).indexOf(keyName) !== -1;
}

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

Tips for sending just the updated section of the form

I am working with a form group where I map the values from the form to an object type in order to make a request to edit the item. This is my form structure: public companyForm = new FormGroup( { generalInfo: new FormGroup({ name: new ...

Typescript - Iterating through CSV columns with precision

I am currently facing a challenge in TypeScript where I need to read a CSV file column by column. Here is an example of the CSV data: Prefix,Suffix Mr,Jr Mrs,Sr After researching on various Stack Overflow questions and reading through TypeScript document ...

Transmit information from child to parent as needed using @input and @output in Angular 2

Is there a way to pass an object from child to parent without relying on @viewChild or services? export class MultiSelectComponent implements OnInit { selectedItems: FormSelectComponentOption[] = []; @Input() items: FormSelectComponentOption[]; @Output ...

The width of the Ion-slide is dynamically determined by the styling

After transitioning my Ionic 2 project to Ionic 3, I encountered issues with ion-slides which are affecting my app's functionality. Upon app loading, specific widths are being defined in the style tags on the slides, disrupting the intended styling. ...

"Enhance Your Text Fields with Angular2 Text Masks for Added Text Formatting

Is there a way to combine text and numbers in my mask? This is what I am currently using: [/\d/, /\d/, /\d/, '-', /\d/, /\d/, /\d/, /\d/] The above code only allows for numbers. How can I modify it to allow f ...

The TypeScript Type inside the Node Module Doesn't Seem to Be Functioning

In my React project, I am using the material-ui@next library along with typescript. Below is the code snippet that I have written: <CardMedia image={item.image_url} style={{ width: 238, height: 124.5 }} /> However, when I try to compile this code, ...

Encountering a Next.js TypeScript Build Error related to the Type 'OmitWithTag<InputFormProps, keyof PageProps, "default">' issue

`I am currently working on a project in Next Js using TypeScript. During the build process with npm run build, I encountered the following errors in the terminal: # Type 'OmitWithTag<InputFormProps, keyof PageProps, "default">' do ...

Retrieve the md-sidenav-layout element within a TypeScript file component

Using md-sidenav in my application has been quite useful. Assigning an object to md-sidenav involves the following syntax: <md-sidenav #start With this syntax, "start" will hold all variables and methods of md-sidenav, allowing for operations such ...

Angular2 emitter does not function properly when using classes in different files

The code provided in this Plunker is functioning well, even when modified with subscribe in the beta version 50. However, it fails to work when the classes are placed in separate files and exported. Is there a way to store the classes in separate files a ...

Error: Issue with accessing the 'get' property of an undefined value (Resolved issue with incompatible imports not functioning)

Encountering an issue while attempting to execute the karma TS spec file. Despite all modules and imports functioning properly without conflicts, the error persists. I've tried incorporating component.ngOninit() into beforeEach() and it(), but to no a ...

Leveraging conditional types and optional variables in Typescript to translate a string into another form

Visit Playground I have been experimenting with creating a versatile function that can map one string to another during the compilation phase. The idea is simple - if a string is provided as input, it should return "data", and if the input is undefined, i ...

The TypeScript error message states that a value of 'undefined' cannot be assigned to a type that expects either a boolean, Connection

I've been grappling with this code snippet for a while now. It was originally written in JavaScript a few months back, but recently I decided to delve into TypeScript. However, I'm struggling to understand how data types are properly defined in T ...

TestCafe has encountered an issue: "There are no tests available to run. This may be due to either the test files not containing any tests or the filter function being too

Attempting to run automated tests using TestCafe resulted in an error when executing the following command. testcafe chrome testc.ts The specified command was used to test the testc.ts file within my Angular application, with TestCafe installed globally ...

Infer the types and flatten arrays within arrays

I am currently working on creating a custom function in typescript that can flatten nested arrays efficiently. My current implementation is as follows: function flattenArrayByKey<T, TProp extends keyof T>(array: T[], prop: TProp): T[TProp] { re ...

The struggle of implementing useReducer and Context in TypeScript: A type error saga

Currently attempting to implement Auth using useReducer and Context in a React application, but encountering a type error with the following code snippet: <UserDispatchContext.Provider value={dispatch}> The error message reads as follows: Type &apos ...

A guide on exposing TypeScript classes globally through a WebPack bundle in JavaScript

Currently delving into TypeScript, my aim is to gradually replace JS with TS. However, due to having numerous JS files, my strategy involves creating new classes in TS and incorporating them into my existing JS files for the time being. Eventually, I plan ...

Implementing a new field in a Node.js model using MongoDB

In my Node.js API, I have a user model working with MongoDB and Angular as the front-end framework. I decided to add a new field named "municipalityDateChange" to my user model. After doing so, I attempted to send an HTTP request from Angular to the Node A ...

How to test Angular HttpClient in protractor end-to-end testing

Upon loading my application, an http call is made to the backend which causes my e2e test to fail in CI pipelines where no backend is available. I attempted to handle the error using the rxjs catchError operator on the http call. Additionally, I tried wr ...

What is the method to retrieve the total number of days in a moment-jalaali using NodeJS?

I'm trying to determine the number of days in the moment-jalaali package for NodeJS. Despite checking their API on GitHub, I couldn't find any reference to a specific method like numOfDay. ...

What is the correct way to implement fetch in a React/Redux/TS application?

Currently, I am developing an application using React, Redux, and TypeScript. I have encountered an issue with Promises and TypeScript. Can you assist me in type-defining functions/Promises? An API call returns a list of post IDs like [1, 2, ..., 1000]. I ...