Sharing Top Content from the Angular-sphere.

Creating A Pipe That Can Consume Component Methods In Angular 4.4.0-RC.0

  • As such, I thought it would be interesting to try and combine the two concepts: what if we could create an Angular Pipe that invoked a component method; but, only when the inputs to that method changed.
  • The “fn” pipe, being pure, would only pass “value” to the “formatValue” method when either the value or the formatValue() references change.
  • Creating this “fn” Pipe is rather simple:

    When a Pipe is invoked in Angular, it receives the input as its first argument; then, subsequent values as its rest arguments.

  • Since the fn Pipe doesn’t have a reference to the contextual component instance, I’m executing the function reference in a null context.
  • In the following App component, I’m going to be formatting a value in two ways: using our fn Pipe and using a vanilla method reference.

Ben Nadel demonstrates how to create a generic Pipe in Angular 4.4.0 that allow you to invoke a component method whenever the inputs to that method change. This reduces the number of times a template value has to be formatted by the component.

@JavaScriptKicks: Creating A Pipe That Can Consume Component Methods In Angular 4.4.0-RC.0 by bennadel #javascript #angularjs

One of the nice things about “pure” Pipes in Angular 4 is that they are only called when their inputs change. In constrast, a component method, when invoked within a component template, is run at least once in every change detection cycle (for the given component). As such, I thought it would be interesting to try and combine the two concepts: what if we could create an Angular Pipe that invoked a component method; but, only when the inputs to that method changed. This would allow us to, essentially, create on-demand Pipe functionality using our component methods.

Run this demo in my JavaScript Demos project on GitHub.

Essentially, what I want to do is create a Pipe that turns around and invokes a public method on the current component. Something like:

{{ value | fn:formatValue }}

… where “value” is the input and “formatValue” is the public method on the current component. The “fn” pipe, being pure, would only pass “value” to the “formatValue” method when either the value or the formatValue() references change. And, since the formatValue() reference will never change, it means the “fn” pipe will only be invoked when the “value” changes.

Creating this “fn” Pipe is rather simple:

When a Pipe is invoked in Angular, it receives the input as its first argument; then, subsequent values as its rest arguments. This means that our function reference – the first “additional” argument – may be sandwiched by values intended to be arguments to the passed-in function reference. As such, we can create the complete function reference arguments by merging the first input into the rest inputs, less the function reference.

Notice, that I am invoking the function reference using the .apply() method. Since the fn Pipe doesn’t have a reference to the contextual component instance, I’m executing the function reference in a null context. This means that the function reference won’t have a “this” context during execution, unless the function is pre-bound to the component (which I am doing in the following code).

Now that we have our fn Pipe, let’s use it in an Angular component. In the following App component, I’m going to be formatting a value in two ways: using our fn Pipe and using a vanilla method reference. I’m using the two approaches so we can see that the Pipe greatly reduces the number of times the formatting is applied:

selector: “my-app”,

styleUrls: [ “./app.component.css” ],

this.message = “Please select a message.”;

// the function. As such, we need to pre-bind it to the component so that we can use

// the proper “this” reference when invoked via the FN PIPE.

public thingOne = ( value: string, suffix: string ) : string => {

console.info( “Calling thingOne().” );

// NOTE: Using this.join() just to demonstrate that the “this” reference works.

return( this.join( value.toUpperCase(), suffix ) );

public thingTwo( value: string, suffix: string ) : string {

console.warn( “Calling thingTwo().” );

// NOTE: Using this.join() just to demonstrate that the “this” reference works.

return( this.join( value.toUpperCase(), suffix ) );

As you can see, we are using two formatting approaches. One that uses the fn pipe:

{{ message | fn:thingOne:”Sweeet!” }}

… and one that uses a method invocation:

{{ thingTwo( message, “Sweeet!” ) }}

And, when we run this application and toggle the message back and forth, we can see how often these two methods are invokes:

It’s a little hard to see what’s going on here (the video makes it clear); but, I clicked on the same setMessage() call several times in a row. And, what we can see is that the “fn:thingOne” approach only invokes the thingOne() method when the message (input) changes. The thingTwo() approach, on the other hand, is invoked twice whenever I click the template link, even if the message hasn’t been changed.

By using a pure Pipe to invoke a component method, we can leverage the memoized functionality of the pipe in order to reduce the number of times that a component method is called. While this may not be broadly applicable, I think this might be a very nice approach when you have complicated formatting that only ever applies to a single component. This would allow such specialization without having to create brand new pipes in Angular.

Creating A Pipe That Can Consume Component Methods In Angular 4.4.0-RC.0

Comments are closed, but trackbacks and pingbacks are open.