Can
Can

Reputation: 693

How to add pipes conditionally and dynamically in Angular?

I have multiple pipes and want to add one or more pipes based on a condition to my input element.

It must be check whether the input element (this) has a certain style (this.styles) and based on that style, a pipe must be added to the input element.

So if the style is ReverseString the pipe reverseStr has to be added to the input element.

I created the pipes, and the pipes work when I add it like (see reverseStr):

<input type="text"
    #formItem
    [name]="id"
    [id]="id"
    class="form-control"
    [ngModel]="value | reverseStr"
    (blur)="change.emit(formItem.value)"/>

But how can I add the pipes conditionally in Angular?

I know it's possible in the HTML by adding something like:

[ngModel]="styles.includes('ReverseString') ? (value | SomePipe) : (value | pipe2)"

But this not the most elegant way I think and if I have multiple input components, I need to change it each time

I created a function like:

addPipe() {
const mapping: any = {
    ReverseString: 'reverseStr',
    LowerCase: 'lowerCase',
    UpperCase: 'upperCase',
};

this.styles.forEach((style : any) => {
    const pipes = mapping[style];
    if (pipes) {
        // How can I add the pipes now dynamically? 
    }
});

}

But I don't know how to add the pipe dynamically to the input field.

How to add pipes conditionally and dynamically in Angular?

Upvotes: 2

Views: 4478

Answers (2)

Basheer Kharoti
Basheer Kharoti

Reputation: 4292

In order to use dynamic Pipes with input, you can just bind ngModel to setters and getters of the component. Here's how you can do that:

1. Bind text input ngModel via Setters and Getters

2. Check for the specific condition on input and use the pipe if evaluates to true

 // component.ts  

 private _value;

  get value() {
    if(this.nameInput) {
      const inputClasses = this.nameInput.nativeElement.getAttribute('class');

      if(inputClasses.indexOf('reverse') !== -1) {
        return (new ReverseStrPipe).transform(this._value);
      } 
    }
    return this._value;
  }

  set value(val) {
    this._value = val;
  }

And

// component.html
<input type="text"
 #nameInput
[(ngModel)]="value"/>

Here's the stackblitz example

Upvotes: 1

Santa
Santa

Reputation: 377

You can have a common pipe component and you can have parameterized pipe in your template,

so something like this in your template,

<input type="text"
    #formItem
    [name]="id"
    [id]="id"
    class="form-control"
    [ngModel]="value | customPipe:desiredStyle"
    (blur)="change.emit(formItem.value)"/>

where 'customPipe' is your pipe and 'desiredStyle' is your parameter(separated by ':'), and you can handle the logic inside your pipe

Kindly refer this stackblitz example to understand better!

Upvotes: 0

Related Questions