| 
									
										
										
										
											2017-05-08 20:47:34 -07:00
										 |  |  | # Pipes
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | Every application starts out with what seems like a simple task: get data, transform them, and show them to users. | 
					
						
							|  |  |  | Getting data could be as simple as creating a local variable or as complex as streaming data over a WebSocket. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-12 14:24:24 -06:00
										 |  |  | Once data arrives, you could push their raw `toString` values directly to the view, | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | but that rarely makes for a good user experience. | 
					
						
							|  |  |  | For example, in most use cases, users prefer to see a date in a simple format like | 
					
						
							|  |  |  | <samp>April 15, 1988</samp> rather than the raw string format | 
					
						
							|  |  |  | <samp>Fri Apr 15 1988 00:00:00 GMT-0700 (Pacific Daylight Time)</samp>. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Clearly, some values benefit from a bit of editing. You may notice that you | 
					
						
							|  |  |  | desire many of the same transformations repeatedly, both within and across many applications. | 
					
						
							|  |  |  | You can almost think of them as styles. | 
					
						
							|  |  |  | In fact, you might like to apply them in your HTML templates as you do styles. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Introducing Angular pipes, a way to write display-value transformations that you can declare in your HTML. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-03 18:08:28 +01:00
										 |  |  | You can run the <live-example></live-example> in Stackblitz and download the code from there. | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | ## Using pipes
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | A pipe takes in data as input and transforms it to a desired output. | 
					
						
							|  |  |  | In this page, you'll use pipes to transform a component's birthday property into | 
					
						
							|  |  |  | a human-friendly date. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-20 20:40:17 +03:00
										 |  |  | <code-example path="pipes/src/app/hero-birthday1.component.ts" header="src/app/hero-birthday1.component.ts"></code-example> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | Focus on the component's template. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-20 20:40:17 +03:00
										 |  |  | <code-example path="pipes/src/app/app.component.html" region="hero-birthday-template" header="src/app/app.component.html"></code-example> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | Inside the interpolation expression, you flow the component's `birthday` value through the | 
					
						
							| 
									
										
										
										
											2017-04-30 22:10:32 +02:00
										 |  |  | [pipe operator](guide/template-syntax#pipe) ( | ) to the [Date pipe](api/common/DatePipe) | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | function on the right. All pipes work this way. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | ## Built-in pipes
 | 
					
						
							|  |  |  | Angular comes with a stock of pipes such as | 
					
						
							|  |  |  | `DatePipe`, `UpperCasePipe`, `LowerCasePipe`, `CurrencyPipe`, and `PercentPipe`. | 
					
						
							|  |  |  | They are all available for use in any template. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-19 15:00:08 -07:00
										 |  |  | <div class="alert is-helpful"> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-30 22:10:32 +02:00
										 |  |  | Read more about these and many other built-in pipes in the [pipes topics](api?type=pipe) of the | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | [API Reference](api); filter for entries that include the word "pipe". | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Angular doesn't have a `FilterPipe` or an `OrderByPipe` for reasons explained in the [Appendix](guide/pipes#no-filter-pipe) of this page. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-10 16:51:13 +01:00
										 |  |  | </div> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | ## Parameterizing a pipe
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | A pipe can accept any number of optional parameters to fine-tune its output. | 
					
						
							|  |  |  | To add parameters to a pipe, follow the pipe name with a colon ( : ) and then the parameter value | 
					
						
							|  |  |  | (such as `currency:'EUR'`). If the pipe accepts multiple parameters, separate the values with colons (such as `slice:1:5`) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Modify the birthday template to give the date pipe a format parameter. | 
					
						
							|  |  |  | After formatting the hero's April 15th birthday, it renders as **<samp>04/15/88</samp>**: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-20 20:40:17 +03:00
										 |  |  | <code-example path="pipes/src/app/app.component.html" region="format-birthday" header="src/app/app.component.html"></code-example> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | The parameter value can be any valid template expression, | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | (see the [Template expressions](guide/template-syntax#template-expressions) section of the | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | [Template Syntax](guide/template-syntax) page) | 
					
						
							|  |  |  | such as a string literal or a component property. | 
					
						
							|  |  |  | In other words, you can control the format through a binding the same way you control the birthday value through a binding. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Write a second component that *binds* the pipe's format parameter | 
					
						
							|  |  |  | to the component's `format` property. Here's the template for that component: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-20 20:40:17 +03:00
										 |  |  | <code-example path="pipes/src/app/hero-birthday2.component.ts" region="template" header="src/app/hero-birthday2.component.ts (template)"></code-example> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | You also added a button to the template and bound its click event to the component's `toggleFormat()` method. | 
					
						
							|  |  |  | That method toggles the component's `format` property between a short form | 
					
						
							|  |  |  | (`'shortDate'`) and a longer form (`'fullDate'`). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-20 20:40:17 +03:00
										 |  |  | <code-example path="pipes/src/app/hero-birthday2.component.ts" region="class" header="src/app/hero-birthday2.component.ts (class)"></code-example> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | As you click the button, the displayed date alternates between | 
					
						
							|  |  |  | "**<samp>04/15/1988</samp>**" and | 
					
						
							|  |  |  | "**<samp>Friday, April 15, 1988</samp>**". | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-11 14:47:51 -08:00
										 |  |  | <div class="lightbox"> | 
					
						
							|  |  |  |   <img src='generated/images/guide/pipes/date-format-toggle-anim.gif' alt="Date Format Toggle"> | 
					
						
							|  |  |  | </div> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-19 15:00:08 -07:00
										 |  |  | <div class="alert is-helpful"> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-30 22:10:32 +02:00
										 |  |  | Read more about the `DatePipe` format options in the [Date Pipe](api/common/DatePipe) | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | API Reference page. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-10 16:51:13 +01:00
										 |  |  | </div> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | ## Chaining pipes
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | You can chain pipes together in potentially useful combinations. | 
					
						
							|  |  |  | In the following example, to display the birthday in uppercase, | 
					
						
							|  |  |  | the birthday is chained to the `DatePipe` and on to the `UpperCasePipe`. | 
					
						
							|  |  |  | The birthday displays as **<samp>APR 15, 1988</samp>**. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-20 20:40:17 +03:00
										 |  |  | <code-example path="pipes/src/app/app.component.html" region="chained-birthday" header="src/app/app.component.html"></code-example> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | This example—which displays **<samp>FRIDAY, APRIL 15, 1988</samp>**—chains | 
					
						
							|  |  |  | the same pipes as above, but passes in a parameter to `date` as well. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-20 20:40:17 +03:00
										 |  |  | <code-example path="pipes/src/app/app.component.html" region="chained-parameter-birthday" header="src/app/app.component.html"></code-example> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | ## Custom pipes
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | You can write your own custom pipes. | 
					
						
							|  |  |  | Here's a custom pipe named `ExponentialStrengthPipe` that can boost a hero's powers: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-20 20:40:17 +03:00
										 |  |  | <code-example path="pipes/src/app/exponential-strength.pipe.ts" header="src/app/exponential-strength.pipe.ts"></code-example> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | This pipe definition reveals the following key points: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | * A pipe is a class decorated with pipe metadata. | 
					
						
							|  |  |  | * The pipe class implements the `PipeTransform` interface's `transform` method that | 
					
						
							|  |  |  | accepts an input value followed by optional parameters and returns the transformed value. | 
					
						
							|  |  |  | * There will be one additional argument to the `transform` method for each parameter passed to the pipe. | 
					
						
							|  |  |  | Your pipe has one such parameter: the `exponent`. | 
					
						
							|  |  |  | * To tell Angular that this is a pipe, you apply the | 
					
						
							| 
									
										
										
										
											2017-03-31 12:23:16 +01:00
										 |  |  | `@Pipe` decorator, which you import from the core Angular library. | 
					
						
							|  |  |  | * The `@Pipe` decorator allows you to define the | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |    pipe name that you'll use within template expressions. It must be a valid JavaScript identifier. | 
					
						
							|  |  |  |    Your pipe's name is `exponentialStrength`. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-19 15:00:08 -07:00
										 |  |  | <div class="alert is-helpful"> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-08 20:47:34 -07:00
										 |  |  | ## The *PipeTransform* interface
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | The `transform` method is essential to a pipe. | 
					
						
							|  |  |  | The `PipeTransform` *interface* defines that method and guides both tooling and the compiler. | 
					
						
							|  |  |  | Technically, it's optional; Angular looks for and executes the `transform` method regardless. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-10 16:51:13 +01:00
										 |  |  | </div> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | Now you need a component to demonstrate the pipe. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-20 20:40:17 +03:00
										 |  |  | <code-example path="pipes/src/app/power-booster.component.ts" header="src/app/power-booster.component.ts"></code-example> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-11 14:47:51 -08:00
										 |  |  | <div class="lightbox"> | 
					
						
							|  |  |  |   <img src='generated/images/guide/pipes/power-booster.png' alt="Power Booster"> | 
					
						
							|  |  |  | </div> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | Note the following: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | * You use your custom pipe the same way you use built-in pipes. | 
					
						
							| 
									
										
										
										
											2019-01-22 12:14:44 +01:00
										 |  |  | * You must include your pipe in the `declarations` array of the `AppModule` | 
					
						
							|  |  |  | * If you choose to inject your pipe into a class, you must provide it in the `providers` array of your `NgModule`. | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-10 16:51:13 +01:00
										 |  |  | <div class="callout is-helpful"> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | <header> | 
					
						
							| 
									
										
										
										
											2017-03-31 12:23:16 +01:00
										 |  |  |   Remember the declarations array | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | </header> | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-03 23:21:14 +01:00
										 |  |  | You must register custom pipes. | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | If you don't, Angular reports an error. | 
					
						
							| 
									
										
										
										
											2018-10-16 15:22:23 -06:00
										 |  |  | The [Angular CLI's](cli) generator registers the pipe automatically. | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-10 16:51:13 +01:00
										 |  |  | </div> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | To probe the behavior in the <live-example></live-example>, | 
					
						
							|  |  |  | change the value and optional exponent in the template. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ## Power Boost Calculator
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | It's not much fun updating the template to test the custom pipe. | 
					
						
							|  |  |  | Upgrade the example to a "Power Boost Calculator" that combines | 
					
						
							|  |  |  | your pipe and two-way data binding with `ngModel`. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-11 13:29:59 +02:00
										 |  |  | <code-example path="pipes/src/app/power-boost-calculator.component.ts" header="src/app/power-boost-calculator.component.ts"> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | </code-example> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-30 20:04:18 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-11 14:47:51 -08:00
										 |  |  | <div class="lightbox"> | 
					
						
							|  |  |  |   <img src='generated/images/guide/pipes/power-boost-calculator-anim.gif' alt="Power Boost Calculator"> | 
					
						
							|  |  |  | </div> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | {@a change-detection} | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | ## Pipes and change detection
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Angular looks for changes to data-bound values through a *change detection* process that runs after every DOM event: | 
					
						
							|  |  |  | every keystroke, mouse move, timer tick, and server response. This could be expensive. | 
					
						
							|  |  |  | Angular strives to lower the cost whenever possible and appropriate. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Angular picks a simpler, faster change detection algorithm when you use a pipe. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-08 20:47:34 -07:00
										 |  |  | <h3 class="no-toc">No pipe</h3> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | In the next example, the component uses the default, aggressive change detection strategy to monitor and update | 
					
						
							| 
									
										
										
										
											2017-03-31 12:23:16 +01:00
										 |  |  | its display of every hero in the `heroes` array. Here's the template: | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-30 20:04:18 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-20 20:40:17 +03:00
										 |  |  | <code-example path="pipes/src/app/flying-heroes.component.html" region="template-1" header="src/app/flying-heroes.component.html (v1)"></code-example> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-31 12:23:16 +01:00
										 |  |  | The companion component class provides heroes, adds heroes into the array, and can reset the array. | 
					
						
							| 
									
										
										
										
											2017-03-30 20:04:18 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-20 20:40:17 +03:00
										 |  |  | <code-example path="pipes/src/app/flying-heroes.component.ts" region="v1" header="src/app/flying-heroes.component.ts (v1)"></code-example> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | You can add heroes and Angular updates the display when you do. | 
					
						
							| 
									
										
										
										
											2017-03-31 12:23:16 +01:00
										 |  |  | If you click the `reset` button, Angular replaces `heroes` with a new array of the original heroes and updates the display. | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | If you added the ability to remove or change a hero, Angular would detect those changes and update the display as well. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-08 20:47:34 -07:00
										 |  |  | <h3 class="no-toc"><i>FlyingHeroesPipe</i></h3> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | Add a `FlyingHeroesPipe` to the `*ngFor` repeater that filters the list of heroes to just those heroes who can fly. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-20 20:40:17 +03:00
										 |  |  | <code-example path="pipes/src/app/flying-heroes.component.html" region="template-flying-heroes" header="src/app/flying-heroes.component.html (flyers)"></code-example> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | Here's the `FlyingHeroesPipe` implementation, which follows the pattern for custom pipes described earlier. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-20 20:40:17 +03:00
										 |  |  | <code-example path="pipes/src/app/flying-heroes.pipe.ts" region="pure" header="src/app/flying-heroes.pipe.ts"></code-example> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | Notice the odd behavior in the <live-example></live-example>: | 
					
						
							|  |  |  | when you add flying heroes, none of them are displayed under "Heroes who fly." | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Although you're not getting the behavior you want, Angular isn't broken. | 
					
						
							|  |  |  | It's just using a different change-detection algorithm that ignores changes to the list or any of its items. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Notice how a hero is added: | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-20 20:40:17 +03:00
										 |  |  | <code-example path="pipes/src/app/flying-heroes.component.ts" region="push" header="src/app/flying-heroes.component.ts"></code-example> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-26 21:35:03 +07:00
										 |  |  | You add the hero into the `heroes` array. The reference to the array hasn't changed. | 
					
						
							| 
									
										
										
										
											2017-03-31 12:23:16 +01:00
										 |  |  | It's the same array. That's all Angular cares about. From its perspective, *same array, no change, no display update*. | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-31 12:23:16 +01:00
										 |  |  | To fix that, create an array with the new hero appended and assign that to `heroes`. | 
					
						
							|  |  |  | This time Angular detects that the array reference has changed. | 
					
						
							|  |  |  | It executes the pipe and updates the display with the new array, which includes the new flying hero. | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-31 12:23:16 +01:00
										 |  |  | If you *mutate* the array, no pipe is invoked and the display isn't updated; | 
					
						
							|  |  |  | if you *replace* the array, the pipe executes and the display is updated. | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | The Flying Heroes application extends the | 
					
						
							|  |  |  | code with checkbox switches and additional displays to help you experience these effects. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-30 20:04:18 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-11 14:47:51 -08:00
										 |  |  | <div class="lightbox"> | 
					
						
							|  |  |  |   <img src='generated/images/guide/pipes/flying-heroes-anim.gif' alt="Flying Heroes"> | 
					
						
							|  |  |  | </div> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-31 12:23:16 +01:00
										 |  |  | Replacing the array is an efficient way to signal Angular to update the display. | 
					
						
							| 
									
										
										
										
											2018-11-21 13:49:39 +00:00
										 |  |  | When do you replace the array? When the data changes. | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | That's an easy rule to follow in *this* example | 
					
						
							|  |  |  | where the only way to change the data is by adding a hero. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-21 13:49:39 +00:00
										 |  |  | More often, you don't know when the data has changed, | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | especially in applications that mutate data in many ways, | 
					
						
							|  |  |  | perhaps in application locations far away. | 
					
						
							|  |  |  | A component in such an application usually can't know about those changes. | 
					
						
							|  |  |  | Moreover, it's unwise to distort the component design to accommodate a pipe. | 
					
						
							|  |  |  | Strive to keep the component class independent of the HTML. | 
					
						
							|  |  |  | The component should be unaware of pipes. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | For filtering flying heroes, consider an *impure pipe*. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | ## Pure and impure pipes
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | There are two categories of pipes: *pure* and *impure*. | 
					
						
							|  |  |  | Pipes are pure by default. Every pipe you've seen so far has been pure. | 
					
						
							|  |  |  | You make a pipe impure by setting its pure flag to false. You could make the `FlyingHeroesPipe` | 
					
						
							|  |  |  | impure like this: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-20 20:40:17 +03:00
										 |  |  | <code-example path="pipes/src/app/flying-heroes.pipe.ts" region="pipe-decorator" header="src/app/flying-heroes.pipe.ts"></code-example> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | Before doing that, understand the difference between pure and impure, starting with a pure pipe. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-08 20:47:34 -07:00
										 |  |  | <h3 class="no-toc">Pure pipes</h3> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | Angular executes a *pure pipe* only when it detects a *pure change* to the input value. | 
					
						
							|  |  |  | A pure change is either a change to a primitive input value (`String`, `Number`, `Boolean`, `Symbol`) | 
					
						
							|  |  |  | or a changed object reference (`Date`, `Array`, `Function`, `Object`). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Angular ignores changes within (composite) objects. | 
					
						
							| 
									
										
										
										
											2017-03-31 12:23:16 +01:00
										 |  |  | It won't call a pure pipe if you change an input month, add to an input array, or update an input object property. | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | This may seem restrictive but it's also fast. | 
					
						
							|  |  |  | An object reference check is fast—much faster than a deep check for | 
					
						
							|  |  |  | differences—so Angular can quickly determine if it can skip both the | 
					
						
							|  |  |  | pipe execution and a view update. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | For this reason, a pure pipe is preferable when you can live with the change detection strategy. | 
					
						
							|  |  |  | When you can't, you *can* use the impure pipe. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-19 15:00:08 -07:00
										 |  |  | <div class="alert is-helpful"> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | Or you might not use a pipe at all. | 
					
						
							|  |  |  | It may be better to pursue the pipe's purpose with a property of the component, | 
					
						
							|  |  |  | a point that's discussed later in this page. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-10 16:51:13 +01:00
										 |  |  | </div> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-08 20:47:34 -07:00
										 |  |  | <h3 class="no-toc">Impure pipes</h3> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | Angular executes an *impure pipe*  during every component change detection cycle. | 
					
						
							|  |  |  | An impure pipe is called often, as often as every keystroke or mouse-move. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | With that concern in mind, implement an impure pipe with great care. | 
					
						
							|  |  |  | An expensive, long-running pipe could destroy the user experience. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | {@a impure-flying-heroes} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-08 20:47:34 -07:00
										 |  |  | <h3 class="no-toc">An impure <i>FlyingHeroesPipe</i></h3> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | A flip of the switch turns the `FlyingHeroesPipe` into a `FlyingHeroesImpurePipe`. | 
					
						
							|  |  |  | The complete implementation is as follows: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | <code-tabs> | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-11 13:29:59 +02:00
										 |  |  |   <code-pane header="FlyingHeroesImpurePipe" path="pipes/src/app/flying-heroes.pipe.ts" region="impure"> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |   </code-pane> | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-11 13:29:59 +02:00
										 |  |  |   <code-pane header="FlyingHeroesPipe" path="pipes/src/app/flying-heroes.pipe.ts" region="pure"> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |   </code-pane> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | </code-tabs> | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | You inherit from `FlyingHeroesPipe` to prove the point that nothing changed internally. | 
					
						
							|  |  |  | The only difference is the `pure` flag in the pipe metadata. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | This is a good candidate for an impure pipe because the `transform` function is trivial and fast. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-20 20:40:17 +03:00
										 |  |  | <code-example path="pipes/src/app/flying-heroes.pipe.ts" header="src/app/flying-heroes.pipe.ts (filter)" region="filter"></code-example> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | You can derive a `FlyingHeroesImpureComponent` from `FlyingHeroesComponent`. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-20 20:40:17 +03:00
										 |  |  | <code-example path="pipes/src/app/flying-heroes-impure.component.html" header="src/app/flying-heroes-impure.component.html (excerpt)" region="template-flying-heroes"></code-example> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | The only substantive change is the pipe in the template. | 
					
						
							|  |  |  | You can confirm in the <live-example></live-example> that the _flying heroes_ | 
					
						
							| 
									
										
										
										
											2017-03-31 12:23:16 +01:00
										 |  |  | display updates as you add heroes, even when you mutate the `heroes` array. | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-30 20:04:18 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-08 20:47:34 -07:00
										 |  |  | {@a async-pipe} | 
					
						
							|  |  |  | <h3 class="no-toc">The impure <i>AsyncPipe</i></h3> | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | The Angular `AsyncPipe` is an interesting example of an impure pipe. | 
					
						
							| 
									
										
										
										
											2017-03-31 12:23:16 +01:00
										 |  |  | The `AsyncPipe` accepts a `Promise` or `Observable` as input | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | and subscribes to the input automatically, eventually returning the emitted values. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The `AsyncPipe` is also stateful. | 
					
						
							| 
									
										
										
										
											2017-03-31 12:23:16 +01:00
										 |  |  | The pipe maintains a subscription to the input `Observable` and | 
					
						
							|  |  |  | keeps delivering values from that `Observable` as they arrive. | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-31 12:23:16 +01:00
										 |  |  | This next example binds an `Observable` of message strings | 
					
						
							|  |  |  | (`message$`) to a view with the `async` pipe. | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-30 20:04:18 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-11 13:29:59 +02:00
										 |  |  | <code-example path="pipes/src/app/hero-async-message.component.ts" header="src/app/hero-async-message.component.ts"> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | </code-example> | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | The Async pipe saves boilerplate in the component code. | 
					
						
							|  |  |  | The component doesn't have to subscribe to the async data source, | 
					
						
							|  |  |  | extract the resolved values and expose them for binding, | 
					
						
							|  |  |  | and have to unsubscribe when it's destroyed | 
					
						
							|  |  |  | (a potent source of memory leaks). | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-08 20:47:34 -07:00
										 |  |  | <h3 class="no-toc">An impure caching pipe</h3> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | Write one more impure pipe, a pipe that makes an HTTP request. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Remember that impure pipes are called every few milliseconds. | 
					
						
							|  |  |  | If you're not careful, this pipe will punish the server with requests. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-21 13:49:39 +00:00
										 |  |  | In the following code, the pipe only calls the server when the requested URL changes and it caches the server response. | 
					
						
							| 
									
										
										
										
											2018-02-10 13:42:54 +09:00
										 |  |  | The code uses the [Angular http](guide/http) client to retrieve data: | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-30 20:04:18 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-11 13:29:59 +02:00
										 |  |  | <code-example path="pipes/src/app/fetch-json.pipe.ts" header="src/app/fetch-json.pipe.ts"> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | </code-example> | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | Now demonstrate it in a harness component whose template defines two bindings to this pipe, | 
					
						
							|  |  |  | both requesting the heroes from the `heroes.json` file. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-11 13:29:59 +02:00
										 |  |  | <code-example path="pipes/src/app/hero-list.component.ts" header="src/app/hero-list.component.ts"> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | </code-example> | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | The component renders as the following: | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-30 20:04:18 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-11 14:47:51 -08:00
										 |  |  | <div class="lightbox"> | 
					
						
							|  |  |  |   <img src='generated/images/guide/pipes/hero-list.png' alt="Hero List"> | 
					
						
							|  |  |  | </div> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | A breakpoint on the pipe's request for data shows the following: | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | * Each binding gets its own pipe instance. | 
					
						
							|  |  |  | * Each pipe instance caches its own URL and data. | 
					
						
							|  |  |  | * Each pipe instance only calls the server once. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-08 20:47:34 -07:00
										 |  |  | <h3 class="no-toc"><i>JsonPipe</i></h3> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | In the previous code sample, the second `fetch` pipe binding demonstrates more pipe chaining. | 
					
						
							|  |  |  | It displays the same hero data in JSON format by chaining through to the built-in `JsonPipe`. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-10 16:51:13 +01:00
										 |  |  | <div class="callout is-helpful"> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-30 20:04:18 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | <header> | 
					
						
							|  |  |  |   Debugging with the json pipe | 
					
						
							|  |  |  | </header> | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-30 22:10:32 +02:00
										 |  |  | The [JsonPipe](api/common/JsonPipe) | 
					
						
							| 
									
										
										
										
											2019-06-10 13:56:49 +03:00
										 |  |  | provides an easy way to diagnose a mysteriously failing data binding or | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | inspect an object for future binding. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-10 16:51:13 +01:00
										 |  |  | </div> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | {@a pure-pipe-pure-fn} | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-08 20:47:34 -07:00
										 |  |  | <h3 class="no-toc">Pure pipes and pure functions</h3> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | A pure pipe uses pure functions. | 
					
						
							|  |  |  | Pure functions process inputs and return values without detectable side effects. | 
					
						
							|  |  |  | Given the same input, they should always return the same output. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The pipes discussed earlier in this page are implemented with pure functions. | 
					
						
							|  |  |  | The built-in `DatePipe` is a pure pipe with a pure function implementation. | 
					
						
							|  |  |  | So are the `ExponentialStrengthPipe` and `FlyingHeroesPipe`. | 
					
						
							|  |  |  | A few steps back, you reviewed the `FlyingHeroesImpurePipe`—an impure pipe with a pure function. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | But always implement a *pure pipe* with a *pure function*. | 
					
						
							|  |  |  | Otherwise, you'll see many console errors regarding expressions that changed after they were checked. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | ## Next steps
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Pipes are a great way to encapsulate and share common display-value | 
					
						
							|  |  |  | transformations. Use them like styles, dropping them | 
					
						
							|  |  |  | into your template's expressions to enrich the appeal and usability | 
					
						
							|  |  |  | of your views. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-30 22:10:32 +02:00
										 |  |  | Explore Angular's inventory of built-in pipes in the [API Reference](api?type=pipe). | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | Try writing a custom pipe and perhaps contributing it to the community. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | {@a no-filter-pipe} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | ## Appendix: No *FilterPipe* or *OrderByPipe*
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Angular doesn't provide pipes for filtering or sorting lists. | 
					
						
							|  |  |  | Developers familiar with AngularJS know these as `filter` and `orderBy`. | 
					
						
							|  |  |  | There are no equivalents in Angular. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | This isn't an oversight. Angular doesn't offer such pipes because | 
					
						
							|  |  |  | they perform poorly and prevent aggressive minification. | 
					
						
							|  |  |  | Both `filter` and `orderBy` require parameters that reference object properties. | 
					
						
							|  |  |  | Earlier in this page, you learned that such pipes must be [impure](guide/pipes#pure-and-impure-pipes) and that | 
					
						
							|  |  |  | Angular calls impure pipes in almost every change-detection cycle. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Filtering and especially sorting are expensive operations. | 
					
						
							|  |  |  | The user experience can degrade severely for even moderate-sized lists when Angular calls these pipe methods many times per second. | 
					
						
							|  |  |  | `filter` and `orderBy` have often been abused in AngularJS apps, leading to complaints that Angular itself is slow. | 
					
						
							|  |  |  | That charge is fair in the indirect sense that AngularJS prepared this performance trap | 
					
						
							|  |  |  | by offering `filter` and `orderBy` in the first place. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The minification hazard is also compelling, if less obvious. Imagine a sorting pipe applied to a list of heroes. | 
					
						
							|  |  |  | The list might be sorted by hero `name` and `planet` of origin properties in the following way: | 
					
						
							| 
									
										
										
										
											2017-03-30 20:04:18 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | <code-example language="html"> | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  |   <!-- NOT REAL CODE! --> | 
					
						
							|  |  |  |   <div *ngFor="let hero of heroes | orderBy:'name,planet'"></div> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | </code-example> | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | You identify the sort fields by text strings, expecting the pipe to reference a property value by indexing | 
					
						
							|  |  |  | (such as `hero['name']`). | 
					
						
							|  |  |  | Unfortunately, aggressive minification manipulates the `Hero` property names so that `Hero.name` and `Hero.planet` | 
					
						
							|  |  |  | become something like `Hero.a` and `Hero.b`. Clearly `hero['name']` doesn't work. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | While some may not care to minify this aggressively, | 
					
						
							|  |  |  | the Angular product shouldn't prevent anyone from minifying aggressively. | 
					
						
							|  |  |  | Therefore, the Angular team decided that everything Angular provides will minify safely. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The Angular team and many experienced Angular developers strongly recommend moving | 
					
						
							|  |  |  | filtering and sorting logic into the component itself. | 
					
						
							|  |  |  | The component can expose a `filteredHeroes` or `sortedHeroes` property and take control | 
					
						
							|  |  |  | over when and how often to execute the supporting logic. | 
					
						
							|  |  |  | Any capabilities that you would have put in a pipe and shared across the app can be | 
					
						
							|  |  |  | written in a filtering/sorting service and injected into the component. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | If these performance and minification considerations don't apply to you, you can always create your own such pipes | 
					
						
							| 
									
										
										
										
											2017-04-26 15:11:02 +03:00
										 |  |  | (similar to the [FlyingHeroesPipe](guide/pipes#impure-flying-heroes)) or find them in the community. |