From 4097c67b59bb2f792ee4c68edf04d8aa96ee23a9 Mon Sep 17 00:00:00 2001 From: Foxandxss Date: Fri, 22 Apr 2016 22:57:41 +0200 Subject: [PATCH] chore: rename Elvis to safe navigation operator closes #1139 --- .../dart/lib/app_component.html | 28 ++++----- .../template-syntax/ts/app/app.component.html | 30 +++++----- .../dart/latest/guide/template-syntax.jade | 30 +++++----- .../docs/ts/latest/guide/template-syntax.jade | 58 +++++++++---------- public/docs/ts/latest/guide/upgrade.jade | 2 +- 5 files changed, 74 insertions(+), 74 deletions(-) diff --git a/public/docs/_examples/template-syntax/dart/lib/app_component.html b/public/docs/_examples/template-syntax/dart/lib/app_component.html index 41732b3345..ba6499c90b 100644 --- a/public/docs/_examples/template-syntax/dart/lib/app_component.html +++ b/public/docs/_examples/template-syntax/dart/lib/app_component.html @@ -34,7 +34,7 @@ Template local variables
Inputs and outputs
Pipes
-Elvis ?.
+Safe navigation operator ?.
@@ -738,25 +738,25 @@ bindon-ngModel top - -

Elvis ?.

+ +

Safe navigation operator ?.

- + The title is {{ title }} - +
- + The current hero's name is {{currentHero?.firstName}} - +
- + The current hero's name is {{currentHero.firstName}} - +
@@ -768,18 +768,18 @@ The null hero's name is {{nullHero.firstName}} EXCEPTION: The null object does not have a getter 'firstName'. --> - +
The null hero's name is {{nullHero.firstName}}
- + - +
- + The null hero's name is {{nullHero?.firstName}} - +
diff --git a/public/docs/_examples/template-syntax/ts/app/app.component.html b/public/docs/_examples/template-syntax/ts/app/app.component.html index 4de9728c11..2eca4116e7 100644 --- a/public/docs/_examples/template-syntax/ts/app/app.component.html +++ b/public/docs/_examples/template-syntax/ts/app/app.component.html @@ -34,7 +34,7 @@ Template local variables
Inputs and outputs
Pipes
-Elvis ?.
+Safe navigation operator ?.
Enums
@@ -739,25 +739,25 @@ After setClasses(), the classes are "{{classDiv.className}}" top - -

Elvis ?.

+ +

Safe navigation operator ?.

- + The title is {{ title }} - +
- + The current hero's name is {{currentHero?.firstName}} - +
- + The current hero's name is {{currentHero.firstName}} - +
@@ -768,22 +768,22 @@ See console log TypeError: Cannot read property 'firstName' of null in [null] --> - +
The null hero's name is {{nullHero.firstName}}
- +
- + The null hero's name is {{nullHero && nullHero.firstName}} - +
- + The null hero's name is {{nullHero?.firstName}} - +
diff --git a/public/docs/dart/latest/guide/template-syntax.jade b/public/docs/dart/latest/guide/template-syntax.jade index 8d116d645b..c3469db32d 100644 --- a/public/docs/dart/latest/guide/template-syntax.jade +++ b/public/docs/dart/latest/guide/template-syntax.jade @@ -366,11 +366,11 @@ table :marked ## Template expression operators The template expression language employs a subset of Dart syntax supplemented with a few special operators - for specific scenarios. We'll cover two of these operators: _pipe_ and _Elvis_. + for specific scenarios. We'll cover two of these operators: _pipe_ and _safe navigation operator_. .callout.is-helpful header Dart difference: ?. is a Dart operator :marked - The Elvis operator (`?.`) is part of the Dart language. + The safe navigation operator (`?.`) is part of the Dart language. It's considered a template expression operator because Angular 2 supports `?.` even in TypeScript and JavaScript apps. +includeShared('{ts}', 'expression-operators-pipe-1') @@ -383,28 +383,28 @@ table NOTE: Intentionally omit discussion of the json pipe. +includeShared('{ts}', 'expression-operators-pipe-4') +makeExample('template-syntax/dart/lib/app_component.html', 'pipes-json')(format=".") -+includeShared('{ts}', 'expression-operators-elvis-1') -+makeExample('template-syntax/dart/lib/app_component.html', 'elvis-2')(format=".") -+includeShared('{ts}', 'expression-operators-elvis-2') -+makeExample('template-syntax/dart/lib/app_component.html', 'elvis-1')(format=".") -+includeShared('{ts}', 'expression-operators-elvis-3') -// +includeShared('{ts}', 'expression-operators-elvis-4') ++includeShared('{ts}', 'expression-operators-safe-1') ++makeExample('template-syntax/dart/lib/app_component.html', 'safe-2')(format=".") ++includeShared('{ts}', 'expression-operators-safe-2') ++makeExample('template-syntax/dart/lib/app_component.html', 'safe-1')(format=".") ++includeShared('{ts}', 'expression-operators-safe-3') +// +includeShared('{ts}', 'expression-operators-safe-4') :marked Dart throws an exception, and so does Angular: code-example(format="" language="html"). EXCEPTION: The null object does not have a getter 'firstName'. -+includeShared('{ts}', 'expression-operators-elvis-5') -+makeExample('template-syntax/dart/lib/app_component.html', 'elvis-4')(format=".") ++includeShared('{ts}', 'expression-operators-safe-5') ++makeExample('template-syntax/dart/lib/app_component.html', 'safe-4')(format=".") // NOTE: Intentionally skip ugly null checking you wouldn't do in Dart. - That means skipping the shared sections 'expression-operators-elvis-6' & 7, - plus the example 'elvis-5'. + That means skipping the shared sections 'expression-operators-safe-6' & 7, + plus the example 'safe-5'. :marked This approach has merit but can be cumbersome, especially if the property path is long. Imagine guarding against a null somewhere in a long property path such as `a.b.c.d`. -+includeShared('{ts}', 'expression-operators-elvis-8') -+makeExample('template-syntax/dart/lib/app_component.html', 'elvis-6')(format=".") -+includeShared('{ts}', 'expression-operators-elvis-9') ++includeShared('{ts}', 'expression-operators-safe-8') ++makeExample('template-syntax/dart/lib/app_component.html', 'safe-6')(format=".") ++includeShared('{ts}', 'expression-operators-safe-9') +includeShared('{ts}', 'summary') diff --git a/public/docs/ts/latest/guide/template-syntax.jade b/public/docs/ts/latest/guide/template-syntax.jade index c0c9ef16ad..2eda5f7643 100644 --- a/public/docs/ts/latest/guide/template-syntax.jade +++ b/public/docs/ts/latest/guide/template-syntax.jade @@ -28,7 +28,7 @@ include ../_util-fns * [Input and output properties](#inputs-outputs) * [Template expression operators](#expression-operators) * [pipe](#pipe) - * ["elvis" (?.)](#elvis) + * ["safe navigation operator" (?.)](#safe-navigation-operator) // #enddocregion intro .l-sub-section :marked @@ -1576,7 +1576,7 @@ figure.image-display :marked ## Template expression operators The template expression language employs a subset of JavaScript syntax supplemented with a few special operators - for specific scenarios. We'll cover two of these operators: _pipe_ and _Elvis_. + for specific scenarios. We'll cover two of these operators: _pipe_ and _safe navigation operator_. // #enddocregion expression-operators // #docregion expression-operators-pipe-1 @@ -1608,23 +1608,23 @@ figure.image-display // #enddocregion expression-operators-pipe-4 +makeExample('template-syntax/ts/app/app.component.html', 'pipes-json')(format=".") -// #docregion expression-operators-elvis-1 +// #docregion expression-operators-safe-1 :marked - - ### The Elvis operator ( ?. ) and null property paths + + ### The safe navigation operator ( ?. ) and null property paths - The Angular **Elvis operator (`?.`)** — perhaps better described as the "safe navigation operator" — is a fluent and convenient way to guard against null and undefined values in property paths. + The Angular **safe navigation operator (`?.`)** is a fluent and convenient way to guard against null and undefined values in property paths. Here it is, protecting against a view render failure if the `currentHero` is null. -// #enddocregion expression-operators-elvis-1 -+makeExample('template-syntax/ts/app/app.component.html', 'elvis-2')(format=".") -// #docregion expression-operators-elvis-2 +// #enddocregion expression-operators-safe-1 ++makeExample('template-syntax/ts/app/app.component.html', 'safe-2')(format=".") +// #docregion expression-operators-safe-2 :marked Let’s elaborate on the problem and this particular solution. What happens when the following data bound `title` property is null? -// #enddocregion expression-operators-elvis-2 -+makeExample('template-syntax/ts/app/app.component.html', 'elvis-1')(format=".") -// #docregion expression-operators-elvis-3 +// #enddocregion expression-operators-safe-2 ++makeExample('template-syntax/ts/app/app.component.html', 'safe-1')(format=".") +// #docregion expression-operators-safe-3 :marked The view still renders but the displayed value is blank; we see only "The title is" with nothing after it. That is reasonable behavior. At least the app doesn't crash. @@ -1634,14 +1634,14 @@ figure.image-display code-example(format="" language="html"). The null hero's name is {{nullHero.firstName}} -// #enddocregion expression-operators-elvis-3 -// #docregion expression-operators-elvis-4 +// #enddocregion expression-operators-safe-3 +// #docregion expression-operators-safe-4 :marked JavaScript throws a null reference error, and so does Angular: code-example(format="" language="html"). TypeError: Cannot read property 'firstName' of null in [null] -// #enddocregion expression-operators-elvis-4 -// #docregion expression-operators-elvis-5 +// #enddocregion expression-operators-safe-4 +// #docregion expression-operators-safe-5 :marked Worse, the *entire view disappears*. @@ -1659,30 +1659,30 @@ code-example(format="" language="html"). Unfortunately, our app crashes when the `currentHero` is null. We could code around that problem with [NgIf](#ngIf). -// #enddocregion expression-operators-elvis-5 -+makeExample('template-syntax/ts/app/app.component.html', 'elvis-4')(format=".") -// #docregion expression-operators-elvis-6 +// #enddocregion expression-operators-safe-5 ++makeExample('template-syntax/ts/app/app.component.html', 'safe-4')(format=".") +// #docregion expression-operators-safe-6 :marked Or we could try to chain parts of the property path with `&&`, knowing that the expression bails out when it encounters the first null. -// #enddocregion expression-operators-elvis-6 -+makeExample('template-syntax/ts/app/app.component.html', 'elvis-5')(format=".") -// #docregion expression-operators-elvis-7 +// #enddocregion expression-operators-safe-6 ++makeExample('template-syntax/ts/app/app.component.html', 'safe-5')(format=".") +// #docregion expression-operators-safe-7 :marked These approaches have merit but can be cumbersome, especially if the property path is long. Imagine guarding against a null somewhere in a long property path such as `a.b.c.d`. -// #enddocregion expression-operators-elvis-7 -// #docregion expression-operators-elvis-8 +// #enddocregion expression-operators-safe-7 +// #docregion expression-operators-safe-8 :marked - The Angular Elvis operator (`?.`) is a more fluent and convenient way to guard against nulls in property paths. + The Angular safe navigation operator (`?.`) is a more fluent and convenient way to guard against nulls in property paths. The expression bails out when it hits the first null value. The display is blank, but the app keeps rolling without errors. -// #enddocregion expression-operators-elvis-8 -+makeExample('template-syntax/ts/app/app.component.html', 'elvis-6')(format=".") -// #docregion expression-operators-elvis-9 +// #enddocregion expression-operators-safe-8 ++makeExample('template-syntax/ts/app/app.component.html', 'safe-6')(format=".") +// #docregion expression-operators-safe-9 :marked It works perfectly with long property paths such as `a?.b?.c?.d`. -// #enddocregion expression-operators-elvis-9 +// #enddocregion expression-operators-safe-9 // #docregion summary .l-main-section diff --git a/public/docs/ts/latest/guide/upgrade.jade b/public/docs/ts/latest/guide/upgrade.jade index 74903240a7..a1e81c41a4 100644 --- a/public/docs/ts/latest/guide/upgrade.jade +++ b/public/docs/ts/latest/guide/upgrade.jade @@ -1655,7 +1655,7 @@ code-example(format=""). a property expression, as opposed to a literal string. * We've replaced `ng-repeat`s with `*ngFor`s. * We've replaced `ng-click` with an event binding for the standard `click`. - * In all references to `phone`, we're using the elvis operator `?.` for + * In all references to `phone`, we're using the safe navigation operator `?.` for safe property navigation. We need it because when the component first loads, we don't have `phone` yet and the expressions will refer to a non-existing value. Unlike in Angular 1, Angular 2 expressions do not fail silently when