0

I have a navigation component that I want to call a method that applies a custom pipe. When I try to reference it, I get filterPortfolio is not defined in the console.

I am binding this method to a click event in my DOM (the html is applied by the navigation component.

my html:

<div id="filter1" class="miniNavButton" *ngIf="portfolio" (click)="changeFilter('demo')">
    <a>
        <svg class="icon icon-eye">
            <use xlink:href="symbol-defs.svg#icon-eye"></use>
        </svg>
    </a>
</div>

portfolio.component.ts:

import { Component } from 'angular2/core';
import {ViewEncapsulation} from 'angular2/core';
import {Pipe, PipeTransform} from 'angular2/core';

@Pipe({ name: 'pagesFilter' })
class pagesFilter implements PipeTransform {
    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 {
    pages = [{
        img: './app/images/placeholder.png',
        name: 'veryNiceWords',
        repo: 'https://github.com/Shooshte/veryNiceWords',
        description: 'A hobby app, made to enable posting, rating and sharing quotes over social networks. Work in progress.',
        github: true
    },
        {
            img: './app/images/placeholder.png',
            name: 'ZIC IJS',
            repo: 'https://github.com/Shooshte/ZIC',
            description: 'Refurbishing of on old library webpage with AngularJS.',
            github: true
        },
        {
            img: './app/images/weather.png',
            name: 'Show the Local weather',
            repo: 'http://codepen.io/shooshte/pen/NxOwOX',
            description: 'A freeCodeCamp exercise, designed to show the local weather.',
            demo: true,
            finished: true
        },
        {
            img: './app/images/calculator.png',
            name: 'Calculator',
            repo: 'http://codepen.io/shooshte/pen/qbjJdy',
            description: 'A freeCodeCamp exercise, which requires you to build a javascript calculator.',
            demo: true,
            finished: true
        },
        {
            img: './app/images/github.png',
            name: 'MTGO Draft Replayer',
            repo: 'https://github.com/Shooshte/MTGO-Draft-Replayer',
            description: 'A simple web app that opens a MTGO draft log file, and re-creates the draft from it.',
            github: true
        },
        {
            img: './app/images/codeeval.png',
            name: 'codeEval',
            repo: 'https://github.com/Shooshte/CodeEval',
            description: 'CodeEval challenges solutions written in javascript and posted to gitHub.',
            github: true,
            finished: true
        }];

        filterPortfolio(parameter:String) {
            return this.pages ? 'pagesFilter' : parameter
        };
}

navigation.component.ts

import { Component } from 'angular2/core';
import {ViewEncapsulation} from 'angular2/core';
import { Router, ROUTER_PROVIDERS, ROUTER_DIRECTIVES, RouteConfig } from 'angular2/router';

import { LandingComponent } from './landing.component';
import { PortfolioComponent } from './portfolio.component';
import { SkillsComponent } from './skills.component';
import { ContactComponent } from './contact.component';

@Component({
    selector: 'my-navigation',
    templateUrl: '/app/views/navigation.html',
    styleUrls: ['../app/styles/navigationMobile.css', '../app/styles/navigationOther.css'],
    encapsulation: ViewEncapsulation.None,
    directives: [ROUTER_DIRECTIVES],
    providers: [ROUTER_PROVIDERS]
})

export class NavigationComponent {
    landing = true;
    portfolio = false;

    changeMiniNavLanding = function() {
       this.landing = true;
       this.portfolio = false;
    }

    changeMiniNavPortfolio = function() {
       this.landing = false;
       this.portfolio = true;
    }

    changeFilter(a) {
        PortfolioComponent.apply(filterPortfolio(a));
    }
}

This is the html that iterates trough the pages object (the pages I want to apply the pipe to):

<div class="portfolioContainer">
    <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>

So the portfolio component should export the method to call the filter, that the navigation component should call. I thought this was already done by importing the whole component, but I can't get it to work.

I understand this can be a bit confusing. If it help, here's a github repo of the whole thing - just clone, go to portfolio and run npm start. The relevant files are under views (portfolio.html, navigation.html) and in the app folder (portfolio.component.ts, navigation.component.ts).

Can anybody point out what I'm doing wrong? Thanks.

Miha Šušteršič
  • 8,483
  • 17
  • 69
  • 133

1 Answers1

0

The filterPortfolio method is part of the PortfolioComponent class so you could to call it this way. I think that you don't use the apply method the right way:

PortfolioComponent.prototype.filterPortfolio.apply(this, [a]);

or the call one:

PortfolioComponent.prototype.filterPortfolio.call(this, a);

That being said, I'm not sure that you use the right approach and I can't see any place where you use the pagesFilter pipe in your code.

Günter gave a great answer to such issue in the past. See this question for more details:

Community
  • 1
  • 1
Thierry Templier
  • 182,931
  • 35
  • 372
  • 339
  • thanks for the pointer to the question and the suggestion. I'm still unable to get it to work, so I'll revisit my angular2 lessons, as I think there are some fundamental concepts I'm still not familiar enough with. I will get back to this when I find out what I did wrong :) – Miha Šušteršič Apr 06 '16 at 13:39
  • In fact, I think that you should leverage a shared service to make communicate your components (they don't seem to have a parent / child relation together). See this question for more details: http://stackoverflow.com/questions/34376854/delegation-eventemitter-or-observable-in-angular2/35568924 and this page on angular.io: https://angular.io/docs/ts/latest/cookbook/component-communication.html. I think that your problem is there ;-) – Thierry Templier Apr 06 '16 at 13:44