I have a service that returns a list of pages. Now I want to write a pipe named pagesFilter that returns a list of pages that has this key set as true.
Then I want to apply this filter when clicking on a navigation item.
Somehow I can't get it to work. There are no errors in the console, and the filter variable gets updated correctly. Any advice is appreciated.
My html:
<!-- portfolio submenu -->
<div id="portfolioMenu">
<div id="portfolioMenuOrangeLine"></div>
<div id="filter1" class="miniNavButton" (click)="changeFilter('app demos')">
<a>
<svg class="icon icon-eye">
<use xlink:href="symbol-defs.svg#icon-eye"></use>
</svg>
</a>
</div>
<div id="filter2" class="miniNavButton" (click)="changeFilter('github repos')">
<a>
<svg class="icon icon-embed">
<use xlink:href="symbol-defs.svg#icon-embed"></use>
</svg>
</a>
</div>
<div id="filter3" class="miniNavButton" (click)="changeFilter('work in progress')">
<a>
<svg class="icon icon-hammer">
<use xlink:href="symbol-defs.svg#icon-hammer"></use>
</svg>
</a>
</div>
</div>
<h2 class="filterHeading">Showing: {{ filter }}</h2>
<!-- portfolio content -->
<div class="portfolioContainer">
<div class="displayHack"></div>
<div *ngFor="#p of pages" class="portfolioPageContainer">
<img [attr.src]="p.img" class="portfolioThumbnail">
<h2>{{ p.name }}</h2>
<a [attr.href]="p.repo">
<div>
<p>{{ p.description }}</p>
</div>
<p class="portfolioRepoLink">See the Code!</p>
</a>
</div>
<div class="displayHack"></div>
</div>
pages service:
import { Injectable } from 'angular2/core';
export class Page {
constructor(public img: string, public name: string, public repo: string, public description: string, public demo: boolean, public github: boolean, public finished: boolean) { }
}
@Injectable()
export class PagesService {
getPages() {
return [
new Page('./app/images/placeholder.png', 'veryNiceWords', 'https://github.com/Shooshte/veryNiceWords', 'A hobby app, made to enable posting, rating and sharing quotes over social networks. Work in progress.', false, true, false),
new Page('./app/images/placeholder.png', 'ZIC IJS', 'https://github.com/Shooshte/ZIC', 'Refurbishing of on old library webpage with AngularJS.', false, true, false),
new Page('./app/images/weather.png', 'Show the Local weather', 'http://codepen.io/shooshte/pen/NxOwOX', 'A freeCodeCamp exercise, designed to show the local weather.', true, false, true),
new Page('./app/images/calculator.png', 'Calculator', 'http://codepen.io/shooshte/pen/qbjJdy', 'A freeCodeCamp exercise, which requires you to build a javascript calculator.', true, false, true),
new Page('./app/images/github.png', 'MTGO Draft Replayer', 'https://github.com/Shooshte/MTGO-Draft-Replayer', 'A simple web app that opens a MTGO draft log file, and re-creates the draft from it.', false, true, false),
new Page('./app/images/codeeval.png', 'codeEval', 'https://github.com/Shooshte/CodeEval', 'CodeEval challenges solutions written in javascript and posted to gitHub.', false, true, true)
];
}
}
portfolio component (that uses the service):
import { Component } from 'angular2/core';
import { ViewEncapsulation } from 'angular2/core';
import { Page, PagesService } from './pages.service';
import { Pipe, PipeTransform } from 'angular2/core';
@Pipe({ name: 'filter' })
export class pagesFilter {
transform(pages, [key]): string {
return pages.filter(page => {
return page.hasOwnProperty(key);
});
}
}
@Component({
selector: 'portfolio',
templateUrl: '/app/views/portfolio.html',
styleUrls: ['../app/styles/PortfolioMobile.css', '../app/styles/PortfolioOther.css'],
pipes: [pagesFilter],
encapsulation: ViewEncapsulation.None
})
export class PortfolioComponent {
filter = 'everything';
filterPortfolio(parameter:String) {
return this.pages ? 'pagesFilter' : parameter
}
changeFilter(x) {
this.filter = x;
if (x == 'app demos') {
this.filterPortfolio('demo');
}
else if (x == 'github repos') {
this.filterPortfolio('repo');
}
else if (x == 'miniNavButton') {
this.filterPortfolio('finished');
}
}
pages: Page[];
constructor(private _pagesService: PagesService) { }
ngOnInit() {
this.pages = this._pagesService.getPages();
}
}
You need to provide a parameter to the pipe:
@Pipe ({
name:'filter'
})
export class FilterPipe {
transform(value, params) {
var filter = params[0];
return value.filter((item)=> {
// for example
return (item.name === filter);
});
}
}
You can use this pipe this way basing on a form input and a component property:
@Component({
(...)
template: `
<form>
<input [ngFormControl]="ctrl"/>
</form>
<div *ngFor="#elt of elements | filter:filterValue">{{elt.name}}</div>
`,
pipes: [ FilterPipe ]
})
export class MyComponent {
filterValue:string;
ctrl:Control;
contructor() {
this.control = new Control();
this.control.values.debounceTime(500).subscribe(
(data) => {
this.filterValue = data;
}
);
}
}
Edit
You could also update filterValue
on click events:
@Component({
(...)
template: `
<div (click)="updateFieldValue('new value')">
Update
</div>
<div *ngFor="#elt of elements | filter:filterValue">{{elt.name}}</div>
`,
pipes: [ FilterPipe ]
})
export class MyComponent {
filterValue:string;
updateFilterValue(newValue) {
this.filterValue = newValue;
}
}