diff --git a/public/docs/_examples/pipes/ts/src/app/app.html b/public/docs/_examples/pipes/ts/app/app.component.html similarity index 77% rename from public/docs/_examples/pipes/ts/src/app/app.html rename to public/docs/_examples/pipes/ts/app/app.component.html index efe83db02c..7cbc969c84 100644 --- a/public/docs/_examples/pipes/ts/src/app/app.html +++ b/public/docs/_examples/pipes/ts/app/app.component.html @@ -1,12 +1,11 @@ +
- +
-
-

The hero's birthday is {{ birthday | date }}

@@ -16,8 +15,7 @@
- -

Hero Birthday 2

+

Hero Birthday v.2

loading...
@@ -32,15 +30,18 @@

The chained hero's birthday is - {{ ( birthday | date:'fullDate' ) | uppercase}} + {{ birthday | date:'fullDate' | uppercase}}

- + +

+ The chained hero's birthday is + {{ ( birthday | date:'fullDate' ) | uppercase}} +

+
- loading...
- loading .. diff --git a/public/docs/_examples/pipes/ts/app/app.component.ts b/public/docs/_examples/pipes/ts/app/app.component.ts new file mode 100644 index 0000000000..db6a0c7a81 --- /dev/null +++ b/public/docs/_examples/pipes/ts/app/app.component.ts @@ -0,0 +1,21 @@ +// #docregion +import {Component} from 'angular2/core'; +import {HeroAsyncMessageComponent} from './hero-async-message.component'; +import {HeroBirthday} from './hero-birthday2.component'; +import {HeroListComponent} from './hero-list.component'; +import {PowerBooster} from './power-booster.component'; +import {PowerBoostCalculator} from './power-boost-calculator.component'; + +@Component({ + selector: 'my-app', + templateUrl: 'app/app.component.html', + directives:[ + HeroAsyncMessageComponent, + HeroBirthday, + HeroListComponent, + PowerBooster, PowerBoostCalculator + ] +}) +export class AppComponent { + birthday = new Date(1988,3,15); // April 15, 1988 +} diff --git a/public/docs/_examples/pipes/ts/app/boot.ts b/public/docs/_examples/pipes/ts/app/boot.ts new file mode 100644 index 0000000000..597ab3aa7c --- /dev/null +++ b/public/docs/_examples/pipes/ts/app/boot.ts @@ -0,0 +1,6 @@ +import {bootstrap} from 'angular2/platform/browser'; +import {AppComponent} from './app.component'; +import {HeroBirthday} from './hero-birthday1.component'; + +bootstrap(AppComponent); +bootstrap(HeroBirthday); // v.1 \ No newline at end of file diff --git a/public/docs/_examples/pipes/ts/src/app/exponential-strength-pipe.ts b/public/docs/_examples/pipes/ts/app/exponential-strength.pipe.ts similarity index 75% rename from public/docs/_examples/pipes/ts/src/app/exponential-strength-pipe.ts rename to public/docs/_examples/pipes/ts/app/exponential-strength.pipe.ts index bed8e2dd2e..dae9b3ab6c 100644 --- a/public/docs/_examples/pipes/ts/src/app/exponential-strength-pipe.ts +++ b/public/docs/_examples/pipes/ts/app/exponential-strength.pipe.ts @@ -1,21 +1,18 @@ // #docregion -import {Pipe} from 'angular2/angular2'; -/* +import {Pipe} from 'angular2/core'; +/* * Raise the value exponentially * Takes an exponent argument that defaults to 1. - * Usage: + * Usage: * value | exponentialStrength:exponent * Example: * {{ 2 | exponentialStrength:10}} * formats to: 1024 -*/ -@Pipe({ - name: 'exponentialStrength' -}) +*/ +@Pipe({name: 'exponentialStrength'}) export class ExponentialStrengthPipe { - + transform(value:number, args:string[]) : any { return Math.pow(value, parseInt(args[0] || '1', 10)); } } -// #enddocregion \ No newline at end of file diff --git a/public/docs/_examples/pipes/ts/src/app/fetch-json-pipe.ts b/public/docs/_examples/pipes/ts/app/fetch-json.pipe.ts similarity index 65% rename from public/docs/_examples/pipes/ts/src/app/fetch-json-pipe.ts rename to public/docs/_examples/pipes/ts/app/fetch-json.pipe.ts index a1c61e538b..e9a31bc0ec 100644 --- a/public/docs/_examples/pipes/ts/src/app/fetch-json-pipe.ts +++ b/public/docs/_examples/pipes/ts/app/fetch-json.pipe.ts @@ -1,7 +1,6 @@ -/// - +/// // #docregion -import {Pipe} from 'angular2/angular2'; +import {Pipe} from 'angular2/core'; // #docregion pipe-metadata @Pipe({ @@ -12,13 +11,12 @@ import {Pipe} from 'angular2/angular2'; export class FetchJsonPipe { private fetchedValue:any; private fetchPromise:Promise; + transform(value:string, args:string[]):any { if (!this.fetchPromise) { this.fetchPromise = window.fetch(value) - .then(result => result.json()) - .then(json => { - this.fetchedValue = json; - }); + .then((result:any) => result.json()) + .then((json:any) => this.fetchedValue = json); } return this.fetchedValue; diff --git a/public/docs/_examples/pipes/ts/app/hero-async-message.component.ts b/public/docs/_examples/pipes/ts/app/hero-async-message.component.ts new file mode 100644 index 0000000000..9303932d41 --- /dev/null +++ b/public/docs/_examples/pipes/ts/app/hero-async-message.component.ts @@ -0,0 +1,15 @@ +// #docregion +import {Component} from 'angular2/core'; + +// Initial view: "Message: " +// After 500ms: Message: You are my Hero!" + +@Component({ + selector: 'hero-message', + template: 'Message: {{delayedMessage | async}}', +}) +export class HeroAsyncMessageComponent { + delayedMessage:Promise = new Promise((resolve, reject) => { + setTimeout(() => resolve('You are my Hero!'), 500); + }); +} diff --git a/public/docs/_examples/pipes/ts/app/hero-birthday1.component.ts b/public/docs/_examples/pipes/ts/app/hero-birthday1.component.ts new file mode 100644 index 0000000000..e8ef259381 --- /dev/null +++ b/public/docs/_examples/pipes/ts/app/hero-birthday1.component.ts @@ -0,0 +1,14 @@ +// Version #1 +// #docregion +import {Component} from 'angular2/core' + +@Component({ + selector: 'hero-birthday', + // #docregion hero-birthday-template + template: `

The hero's birthday is {{ birthday | date }}

` + // #enddocregion hero-birthday-template +}) +export class HeroBirthday { + birthday = new Date(1988,3,15); // April 15, 1988 +} +// #enddocregion \ No newline at end of file diff --git a/public/docs/_examples/pipes/ts/src/app/hero-birthday.ts b/public/docs/_examples/pipes/ts/app/hero-birthday2.component.ts similarity index 55% rename from public/docs/_examples/pipes/ts/src/app/hero-birthday.ts rename to public/docs/_examples/pipes/ts/app/hero-birthday2.component.ts index 2b8c5360b3..e0b357c7f4 100644 --- a/public/docs/_examples/pipes/ts/src/app/hero-birthday.ts +++ b/public/docs/_examples/pipes/ts/app/hero-birthday2.component.ts @@ -1,16 +1,24 @@ -import {bootstrap, Component} from 'angular2/angular2' +// Version #2 // #docregion -@Component({ +import {Component} from 'angular2/core' + +@Component({ selector: 'hero-birthday', +// #docregion template template: `

The hero's birthday is {{ birthday | date:format }}

- ` + ` +// #enddocregion template }) +// #docregion class export class HeroBirthday { birthday = new Date(1988,3,15); // April 15, 1988 + + toggle = true; // start with true == shortDate + get format() { return this.toggle ? 'shortDate' : 'fullDate'} - toggle = true; - toggleFormat() { this.toggle = !this.toggle; } + + toggleFormat() { this.toggle = !this.toggle; } } -// #enddocregion +// #enddocregion class diff --git a/public/docs/_examples/pipes/ts/app/hero-list.component.ts b/public/docs/_examples/pipes/ts/app/hero-list.component.ts new file mode 100644 index 0000000000..169767eac1 --- /dev/null +++ b/public/docs/_examples/pipes/ts/app/hero-list.component.ts @@ -0,0 +1,24 @@ +// #docregion +import {Component} from 'angular2/core'; +import {FetchJsonPipe} from './fetch-json.pipe'; + +@Component({ + selector: 'hero-list', + // #docregion template + template: ` +

Heroes from JSON File

+ +
+ {{hero.name}} +
+ +

Heroes as JSON: + {{'heroes.json' | fetch | json}} +

+ `, + // #enddocregion template + pipes: [FetchJsonPipe] +}) +export class HeroListComponent { + /* I've got nothing to do ;-) */ +} diff --git a/public/docs/_examples/pipes/ts/app/power-boost-calculator.component.ts b/public/docs/_examples/pipes/ts/app/power-boost-calculator.component.ts new file mode 100644 index 0000000000..73151d5362 --- /dev/null +++ b/public/docs/_examples/pipes/ts/app/power-boost-calculator.component.ts @@ -0,0 +1,20 @@ +// #docregion +import {Component} from 'angular2/core'; +import {ExponentialStrengthPipe} from './exponential-strength.pipe'; + +@Component({ + selector: 'power-boost-calculator', + template: ` +

Power Boost Calculator

+
Normal power:
+
Boost factor:
+

+ Super Hero Power: {{power | exponentialStrength: factor}} +

+ `, + pipes: [ExponentialStrengthPipe] +}) +export class PowerBoostCalculator { + power = 5; + factor = 1; +} diff --git a/public/docs/_examples/pipes/ts/src/app/power-booster.ts b/public/docs/_examples/pipes/ts/app/power-booster.component.ts similarity index 64% rename from public/docs/_examples/pipes/ts/src/app/power-booster.ts rename to public/docs/_examples/pipes/ts/app/power-booster.component.ts index 071dbb0a75..73d5c25ca0 100644 --- a/public/docs/_examples/pipes/ts/src/app/power-booster.ts +++ b/public/docs/_examples/pipes/ts/app/power-booster.component.ts @@ -1,8 +1,8 @@ // #docregion -import {Component} from 'angular2/angular2' -import {ExponentialStrengthPipe} from './exponential-strength-pipe' +import {Component} from 'angular2/core'; +import {ExponentialStrengthPipe} from './exponential-strength.pipe'; -@Component({ +@Component({ selector: 'power-booster', template: `

Power Booster

diff --git a/public/docs/_examples/pipes/ts/app/window.extension.d.ts b/public/docs/_examples/pipes/ts/app/window.extension.d.ts new file mode 100644 index 0000000000..0a5a71bbf6 --- /dev/null +++ b/public/docs/_examples/pipes/ts/app/window.extension.d.ts @@ -0,0 +1,3 @@ +interface Window { + fetch(url: string, options? : {}) : Promise +} diff --git a/public/docs/_examples/pipes/ts/src/heroes.json b/public/docs/_examples/pipes/ts/heroes.json similarity index 100% rename from public/docs/_examples/pipes/ts/src/heroes.json rename to public/docs/_examples/pipes/ts/heroes.json diff --git a/public/docs/_examples/pipes/ts/index.html b/public/docs/_examples/pipes/ts/index.html new file mode 100644 index 0000000000..9260301954 --- /dev/null +++ b/public/docs/_examples/pipes/ts/index.html @@ -0,0 +1,23 @@ + + + + + Pipes + + + + + + +

Hero Birthday v.1

+ hero-birthday loading... + + my-app loading ... + + + diff --git a/public/docs/_examples/pipes/ts/plnkr.json b/public/docs/_examples/pipes/ts/plnkr.json new file mode 100644 index 0000000000..cc19097a4a --- /dev/null +++ b/public/docs/_examples/pipes/ts/plnkr.json @@ -0,0 +1,8 @@ +{ + "description": "Pipes", + "files":[ + "!**/*.d.ts", + "!**/*.js", + "!**/*.d.ts"], + "tags": ["pipe"] +} \ No newline at end of file diff --git a/public/docs/_examples/pipes/ts/src/app/app.ts b/public/docs/_examples/pipes/ts/src/app/app.ts deleted file mode 100644 index c223b3e0f3..0000000000 --- a/public/docs/_examples/pipes/ts/src/app/app.ts +++ /dev/null @@ -1,52 +0,0 @@ -import {HeroBirthday as HeroBirthday2} from './hero-birthday'; -import {PowerBooster} from './power-booster'; -import {PowerBoostCalculator} from './power-boost-calculator'; -import {HeroListComponent} from './hero-list-component'; - -// #docregion hero-birthday -import {bootstrap, Component} from 'angular2/angular2' - -@Component({ - selector: 'hero-birthday', - // #docregion hero-birthday-template - template: `

The hero's birthday is {{ birthday | date }}

` - // #enddocregion hero-birthday-template -}) -export class HeroBirthday { - birthday = new Date(1988,3,15); // April 15, 1988 -} - -bootstrap(HeroBirthday); -// #enddocregion hero-birthday - -// #docregion async-message -@Component({ - selector: 'my-hero', - template: 'Message: {{delayedMessage | async}}', -}) -class MyHeroAsyncMessageComponent { - delayedMessage:Promise = new Promise((resolve, reject) => { - setTimeout(() => resolve('You are my Hero!'), 500); - }); -} - -// Initial view: "Message: " -// After 500ms: Message: You are my Hero!" -// #enddocregion async-message - -//// Drives the rest of the pipes chapter examples /// - -@Component({ - selector: 'my-app', - templateUrl: 'app/app.html', - directives:[ - HeroBirthday2, - PowerBooster, PowerBoostCalculator, - MyHeroAsyncMessageComponent, - HeroListComponent] -}) -class AppComponent { - birthday = new Date(1988,3,15); // April 15, 1988 -} -bootstrap(AppComponent); - \ No newline at end of file diff --git a/public/docs/_examples/pipes/ts/src/app/hero-list-component.ts b/public/docs/_examples/pipes/ts/src/app/hero-list-component.ts deleted file mode 100644 index 7d4e0974e7..0000000000 --- a/public/docs/_examples/pipes/ts/src/app/hero-list-component.ts +++ /dev/null @@ -1,25 +0,0 @@ -// #docregion -import {bootstrap, Component, - CORE_DIRECTIVES, FORM_DIRECTIVES} from 'angular2/angular2' - -import {FetchJsonPipe} from './fetch-json-pipe' - -@Component({ - selector: 'hero-list', - template: ` -

Heroes from JSON File

- -
- {{hero.name}} -
- -

Heroes as JSON: - {{'heroes.json' | fetch | json}} -

- `, - directives:[CORE_DIRECTIVES], - pipes: [FetchJsonPipe] -}) -export class HeroListComponent { - /* I've got nothing to do ;-) */ -} diff --git a/public/docs/_examples/pipes/ts/src/app/power-boost-calculator.ts b/public/docs/_examples/pipes/ts/src/app/power-boost-calculator.ts deleted file mode 100644 index 7ffad97c7e..0000000000 --- a/public/docs/_examples/pipes/ts/src/app/power-boost-calculator.ts +++ /dev/null @@ -1,21 +0,0 @@ -// #docregion -import {Component, FORM_DIRECTIVES} from 'angular2/angular2' -import {ExponentialStrengthPipe} from './exponential-strength-pipe' - -@Component({ - selector: 'power-boost-calculator', - template: ` -

Power Boost Calculator

-
Normal power:
-
Boost factor:
-

- Super Hero Power: {{power | exponentialStrength: factor}} -

- `, - pipes: [ExponentialStrengthPipe], - directives: [FORM_DIRECTIVES] -}) -export class PowerBoostCalculator { - power = 5; - factor = 1; -} diff --git a/public/docs/_examples/pipes/ts/src/app/window.extension.d.ts b/public/docs/_examples/pipes/ts/src/app/window.extension.d.ts deleted file mode 100644 index c9ffbfb25a..0000000000 --- a/public/docs/_examples/pipes/ts/src/app/window.extension.d.ts +++ /dev/null @@ -1,3 +0,0 @@ -interface Window { - fetch:(url: string, options?: {}) => Promise -} \ No newline at end of file diff --git a/public/docs/_examples/pipes/ts/src/index.html b/public/docs/_examples/pipes/ts/src/index.html deleted file mode 100644 index 9ee62fad92..0000000000 --- a/public/docs/_examples/pipes/ts/src/index.html +++ /dev/null @@ -1,23 +0,0 @@ - - - - - Pipes - - - - - - -

Hero Birthday 1

- loading... -
- loading ... - - - diff --git a/public/docs/_examples/pipes/ts/src/plnkr.json b/public/docs/_examples/pipes/ts/src/plnkr.json deleted file mode 100644 index 2ed4f28391..0000000000 --- a/public/docs/_examples/pipes/ts/src/plnkr.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "files":["!**/*.d.ts", "!**/*.js"] -} \ No newline at end of file diff --git a/public/docs/ts/latest/guide/pipes.jade b/public/docs/ts/latest/guide/pipes.jade index c4ccc5626a..a275b8de87 100644 --- a/public/docs/ts/latest/guide/pipes.jade +++ b/public/docs/ts/latest/guide/pipes.jade @@ -17,7 +17,7 @@ include ../../../../_includes/_util-fns Welcome, Angular pipes, the simple display-value transformations that we can declare in our HTML! - [Live Example](/resources/live-examples/pipes/ts/src/plnkr.html) + [Live Example](/resources/live-examples/pipes/ts/plnkr.html). .l-main-section :marked @@ -25,25 +25,16 @@ include ../../../../_includes/_util-fns A pipe takes in data as input and transforms it to a desired output. We'll illustrate by transforming a component's birthday property into - a human-friendly date. - - Here's a complete mini-app with a `DatePipe`: - - -+makeExample('pipes/ts/src/app/app.ts', 'hero-birthday') + a human-friendly date: ++makeExample('pipes/ts/app/hero-birthday1.component.ts', null, 'app/hero-birthday1.component.ts') :marked - Focus on the component's template to see how we applied the built-in `DatePipe` - while binding the `birthday` property. -+makeExample('pipes/ts/src/app/app.html', 'hero-birthday-template')(format=".") - + Focus on the component's template. ++makeExample('pipes/ts/app/app.component.html', 'hero-birthday-template')(format=".") :marked - Angular [template syntax](./template-syntax.html#pipe) includes a pipe operator ( | ) which we're - using to flow the birthday value on the left through to the `Date` pipe function on the right. - All pipes work this way. + Inside the interpolation expression we flow the component's `birthday` value through the + [pipe operator](./template-syntax.html#pipe) ( | ) to the [Date pipe](../api/common/DatePipe-class.html) + function on the right. All pipes work this way. .l-main-section :marked @@ -64,25 +55,26 @@ include ../../../../_includes/_util-fns We add parameters to a pipe by following the pipe name with a colon ( : ) and then the parameter value (e.g., `currency:'EUR'`). If our pipe accepts multiple parameters, we separate the values with colons (e.g. `slice:1:5`) - We'll modify our birthday example to give the date pipe a format parameter. - The formatted date should display as **04/15/88**. + We'll modify our birthday template to give the date pipe a format parameter. + After formatting the hero's April 15th birthday should display as **04/15/88**. -+makeExample('pipes/ts/src/app/app.html', 'format-birthday')(format=".") ++makeExample('pipes/ts/app/app.component.html', 'format-birthday')(format=".") :marked The parameter value can be any valid [template expression](./template-expression.html#template-expressions) - such as a string literal or a component property. - - Let's revise our example to bind the pipe's format parameter - to the component's `format` property. -+makeExample('pipes/ts/src/app/hero-birthday.ts') - + such as a string literal or a component property. + In other words, we can control the format through a binding the same way we control the birthday value through a binding. + + Let's write a second component that *binds* the pipe's format parameter + to the component's `format` property. Here's the template for that component: ++makeExample('pipes/ts/app/hero-birthday2.component.ts', 'template', 'app/hero-birthday2.component.ts (template)')(format=".") :marked We 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'). - ++makeExample('pipes/ts/app/hero-birthday2.component.ts', 'class', 'app/hero-birthday2.component.ts (class)') +:marked As we click the button, the displayed date alternates between "**04/15/1988**" and "**Friday, April 15, 1988**". @@ -90,6 +82,7 @@ include ../../../../_includes/_util-fns figure.image-display img(src='/resources/images/devguide/pipes/date-format-toggle-anim.gif' alt="Date Format Toggle") :marked + .l-sub-section :marked Learn more about the `DatePipes` format options in the [API Docs](../api/core/DatePipe-class.html). @@ -100,7 +93,7 @@ figure.image-display so we can display the birthday in uppercase. The following birthday displays as **APR 15, 1988** -+makeExample('pipes/ts/src/app/app.html', 'chained-birthday') ++makeExample('pipes/ts/app/app.component.html', 'chained-birthday')(format=".") :marked If we pass a parameter to a filter, we have to add parentheses @@ -108,10 +101,14 @@ figure.image-display The following example displays **FRIDAY, APRIL 15, 1988** -+makeExample('pipes/ts/src/app/app.html', 'chained-parameter-birthday') ++makeExample('pipes/ts/app/app.component.html', 'chained-parameter-birthday')(format=".") .l-sub-section - p Future improvements in the template compiler may eliminate the need for parentheses. + :marked + We can add parentheses to alter the evaluation order or + to provide extra clarity: + +makeExample('pipes/ts/app/app.component.html', 'chained-parameter-birthday-parens')(format=".") +:marked .l-main-section :marked @@ -119,43 +116,39 @@ figure.image-display We can write our own custom pipes. - Let's make a custom pipe named `ExponentialStrengthPipe` - that can boost a hero's powers. - - Create a new file, `exponential-strength-pipe.ts`, and enter the following: - -+makeExample('pipes/ts/src/app/exponential-strength-pipe.ts') + Here's a custom pipe named `ExponentialStrengthPipe` that can boost a hero's powers: ++makeExample('pipes/ts/app/exponential-strength.pipe.ts', null, 'app/exponential-strength.pipe.ts') :marked This pipe definition reveals several key points - * We import the `Pipe` decorator from the Angular library (while getting the usual symbols) - * A pipe is a class - * We decorate the class with the `@Pipe` decorator function. + + * A pipe is a class decorated with pipe metadata. + + * The pipe class implements a `transform` method that + takes an input value and an optional array of parameter strings and returns the transformed value. + + * There will be one item in the parameter array for each parameter passed to the pipe + + * We tell Angular that this is a pipe by applying the + `@Pipe` decorator which we import from the core Angular library. + * The `@Pipe` decorator takes an object with a name property whose value is the pipe name that we'll use within a template expression. It must be a valid JavaScript identifier. Our pipe's name is `exponenentialStrength`. - * The pipe class implements a `transform` method - * `transform` takes a value and an optional array of strings. - The value can be of any type but the arguments array must be an array of strings. - * There will be one item in the array for each parameter passed to the pipe - * `transform` returns a modified value that Angular converts to a string. - Now let's create a component to demonstrate our pipe. -+makeExample('pipes/ts/src/app/power-booster.ts') + + Now we need a component to demonstrate our pipe. ++makeExample('pipes/ts/app/power-booster.component.ts',null,'app/power-booster.component.ts') figure.image-display img(src='/resources/images/devguide/pipes/power-booster.png' alt="Power Booster") :marked Two things to note: - 1. We use the pipe in the template expression exactly as we described in the pipe's comments. - We pass the value to transform from the left and give our pipe an exponent parameter of `10`. + 1. We use our custom pipe the same way we use the built-in pipes. 1. We must list our pipe in the @Component decorator's `pipes` array. -.callout.is-critical +.callout.is-helpful header Remember the pipes array! :marked Angular reports an error if we neglect to list our custom pipe. @@ -163,18 +156,18 @@ figure.image-display Angular built-in pipes are pre-registered. Custom pipes must be registered manually. :marked - If we are inclined to try this in a live-coding tool (such a [plunker](http://plnkr.co/)), + If we try the [live code](/resources/live-examples/pipes/ts/plnkr.html) example, we can probe its behavior by changing the value and the optional exponent in the template. ## Power Boost Calculator (extra-credit) It's not much fun updating the template to test our custom pipe. We could upgrade the example to a "Power Boost Calculator" that combines - our pipe and two-way data binding with `ng-model`. + our pipe and two-way data binding with `ngModel`. -+makeExample('pipes/ts/src/app/power-boost-calculator.ts') ++makeExample('pipes/ts/app/power-boost-calculator.component.ts', null, '/app/power-boost-calculator.component.ts') figure.image-display - img(src='/resources/images/devguide/pipes/power-boost-calculator.png' alt="Power Boost Calculator") + img(src='/resources/images/devguide/pipes/power-boost-calculator-anim.gif' alt="Power Boost Calculator") :marked .l-main-section @@ -200,7 +193,7 @@ figure.image-display It is stateful because the pipe maintains a subscription to the input and its returned values depend on that subscription. In the next example, we bind a simple promise to a view with the async pipe. -+makeExample('pipes/ts/src/app/app.ts', 'async-message') ++makeExample('pipes/ts/app/hero-async-message.component.ts', null, 'app/hero-async-message.component.ts') :marked The Async pipe saves boilerplate in the component code. @@ -219,21 +212,36 @@ figure.image-display Here's how we'll decorate our new stateful `FetchJsonPipe` that makes an HTTP `fetch` request and (eventually) displays the data in the server's response: -+makeExample('pipes/ts/src/app/fetch-json-pipe.ts', 'pipe-metadata') ++makeExample('pipes/ts/app/fetch-json.pipe.ts', 'pipe-metadata','app/fetch-json.pipe.ts (metadata)') :marked Immediately below we have the finished pipe. Its input value is an url to an endpoint that returns a JSON file. The pipe makes a one-time async request to the server and eventually receives the JSON response. -+makeExample('pipes/ts/src/app/fetch-json-pipe.ts') ++makeExample('pipes/ts/app/fetch-json.pipe.ts', null, 'app/fetch-json.pipe.ts') :marked - Next we use this pipe in two template bindings where we - 1. display hero names in an `ng-for` repeater - 1. chain the fetched results to the built-in `JsonPipe` that renders - the data in JSON format - -+makeExample('pipes/ts/src/app/hero-list-component.ts') - + Next we demonstrate this pipe in a test component whose template defines two bindings ++makeExample('pipes/ts/app/hero-list.component.ts', 'template', 'app/hero-list.component.ts (template)') +:marked + The component renders like this: figure.image-display img(src='/resources/images/devguide/pipes/hero-list.png' alt="Hero List") +:marked + The first binding is straight forward. An `ngFor` repeater displays the hero names fetched from a json source file. + We're piping the literal file name, "heroes.json", through to the custom `fetch` pipe. + + ### JsonPipe + The second binding uses more pipe chaining. + We take the same fetched results and display the raw hero data in JSON format + by piping to the built-in `JsonPipe`. + +.callout.is-helpful + header Debugging with the json pipe + :marked + The [JsonPipe](https://angular.io/docs/ts/latest/api/common/JsonPipe-class.html) + is an easy way to diagnosis a mysteriously failing data binding. +:marked + Here's the complete component implementation: ++makeExample('pipes/ts/app/hero-list.component.ts', null, 'app/hero-list.component.ts') +:marked .l-main-section :marked diff --git a/public/resources/images/devguide/pipes/power-boost-calculator-anim.gif b/public/resources/images/devguide/pipes/power-boost-calculator-anim.gif new file mode 100644 index 0000000000..27ff25d115 Binary files /dev/null and b/public/resources/images/devguide/pipes/power-boost-calculator-anim.gif differ