Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamic pipe in Angular 2

Tags:

I'm trying to create a component where you can pass which pipe that should be used for a list inside the component. From what I could find by testing and looking around for answers the only solution appears to create something like:

<my-component myFilter="sortByProperty"></my-component> 

my-component template:

<li *ngFor="#item of list | getPipe:myFilter"></li> 

Which then maps myFilter to the correct pipe logic and runs it, but this seems a bit dirty and not optimal.

I thought they would have come up with a better solution to this problem since Angular 1 where you would also do something along these lines.

Is there not a better way to do this in Angular 2?

like image 686
Chrillewoodz Avatar asked Apr 12 '16 06:04

Chrillewoodz


People also ask

What is a pipe in Angular 2 +?

These filters are known as "Pipes" in Angular 2. Pipes allow us to change the data inside the template. Normally, a pipe takes the data and transforms this input to the desired output. There are many built-in pipes in Angular 2.

Why do we use .pipe in Angular?

Use pipes to transform strings, currency amounts, dates, and other data for display. Pipes are simple functions to use in template expressions to accept an input value and return a transformed value. Pipes are useful because you can use them throughout your application, while only declaring each pipe once.

What is pure and impure pipe in Angular?

A pure pipe is only called when Angular detects a change in the value or the parameters passed to a pipe. An impure pipe is called for every change detection cycle no matter whether the value or parameter(s) changes.


1 Answers

Building on borislemke's answer, here's a solution which does not need eval() and which I find rather clean:

dynamic.pipe.ts:

import {     Injector,     Pipe,     PipeTransform } from '@angular/core';   @Pipe({   name: 'dynamicPipe' }) export class DynamicPipe implements PipeTransform {      public constructor(private injector: Injector) {     }      transform(value: any, pipeToken: any, pipeArgs: any[]): any {         if (!pipeToken) {             return value;         }         else {             let pipe = this.injector.get(pipeToken);             return pipe.transform(value, ...pipeArgs);         }     } } 

app.module.ts:

// … import { DynamicPipe } from './dynamic.pipe';  @NgModule({   declarations: [     // …     DynamicPipe,   ],   imports: [     // …   ],   providers: [     // list all pipes you would like to use     PercentPipe,     ],   bootstrap: [AppComponent] }) export class AppModule { } 

app.component.ts:

import { Component, OnInit } from '@angular/core'; import { PercentPipe } from '@angular/common';  @Component({   selector: 'app-root',   template: `     The following should be a percentage:      {{ myPercentage | dynamicPipe: myPipe:myPipeArgs }}     `,   providers: [] })  export class AppComponent implements OnInit {   myPercentage = 0.5;   myPipe = PercentPipe;   myPipeArgs = []; } 
like image 72
balu Avatar answered Oct 05 '22 23:10

balu