0

I have multiple different pipes that I would like to toggle on and off if the user wants to filter their data by some different criterias. How would I activate/deactivate the pipes currently used in a search or build a single pipe that behaves differently depending on what buttons the user have clicked on?

For example two pipes/filters would look like this...

//cloud.pipe.ts
import {Pipe} from '@angular/core';
import {Hero} from './hero';

@Pipe({
  name: 'Cloud'
})
export class CloudPipe{
  transform(value) {
    if (value == null) {
      return null;
    }
    return value.filter(hero => {
      return hero.cloud === true;
    });
  }
}
//location.pipe.ts
import {Pipe} from '@angular/core';
import {Hero} from './hero';
import { HeroService } from './hero.service';
import { HeroesComponent } from './heroes.component';

@Pipe({
  name: 'Location'
})

export class LocationPipe{
  transform(value) {
    if (value == null) {
      return null;
    }
    return value.filter(hero => {
      return hero.location < 500;
    });
  }
}

Then I would like to have the user toggle different filter buttons and add/remove pipes to the list. What's the best approach for something like this?

<!--Toggle what pipes should be used in search-->
<!--For example how can I construct the "updatePipe" function for doing this?-->
<button id="activateCloud" (click)="updatePipe()"></button>
<button id="activateLocation" (click)="updatePipe()"></button>
<!--Is it possible to have: neither of the pipes active, both at the same time or just one at the time? How can I do this?-->
<div *ngFor="let hero of heroes | Cloud | Location ></div> 

I'd rather not have everything in the same pipe as I would like to extend each pipe to do more in the future. So each pipe should "be it's own" and and work independently from one another but at the same time work in conjunction with other pipes when necessary.

Anton Scotte
  • 439
  • 5
  • 19

1 Answers1

0

You could create a wrapper pipe that forwards to other pipes depending on parameters to be used like

<div *ngFor="let hero of heroes | myPipe:'Cloud':'Location'" ></div> 
@Pipe({
  name: 'myPipe'
})
export class MyPipe{
  locationPipe = new LocationPipe();
  cloudPipe = new CloudPipe();
  constructor() {
    pipes = {
      locationPipe: this.locationPipe,
      cloudPipe: this.clouldPipe
    };
  }

  transform(value, param1, param2) {
    var result = value;
    if(pram1) {
      result = this.pipes[param1].transform(result);
    }
    if(pram2) {
      result = this.pipes[param1].transform(result);
    }
  }
}

or if the pipes list is used as array like

<div *ngFor="let hero of heroes | myPipe:['Cloud':'Location']" ></div> 
@Pipe({
  name: 'myPipe'
})
export class MyPipe{
  locationPipe = new LocationPipe();
  cloudPipe = new CloudPipe();
  constructor() {
    pipes = {
      locationPipe: this.locationPipe,
      cloudPipe: this.clouldPipe
    };
  }

  transform(value, params) {
    var result = value;
    for(var p in params) {
      result = this.pipes[p].transform(result);
    }
  }
}
Günter Zöchbauer
  • 623,577
  • 216
  • 2,003
  • 1,567
  • Thanks for quick answer, this looks promising. I'll check it out later if I can get it to work! – Anton Scotte Jul 31 '16 at 15:05
  • In your example, is LocationPipe the only pipe you export? (Why is LocationPipe the wrapper of "itself" and cloudPipe?) And in this scenario what does new LocationPipe(); refer to? Is it implied that the two pipes (LocationPipe, CloudPipe) are imported from separate files (as in my example) and used to again export a new LocationPipe? Sorry but I don't really follow what is going on. Also I get an error: Property 'pipes' does not exist on type 'LocationPipe' in my typescript compiler. I hope I'm not missing something obvious, could you explain a bit more what is happening in your example? – Anton Scotte Jul 31 '16 at 20:13
  • Sorry, forgot to rename. I updated my answer. The `LocationPipe` and `CloudPipe` are actually not used as pipes but just invoked directly. They could also be injected using the constructor instead. – Günter Zöchbauer Aug 01 '16 at 04:53