Skip to content
This repository has been archived by the owner on Dec 4, 2017. It is now read-only.

Commit

Permalink
chore: rename Elvis to safe navigation operator
Browse files Browse the repository at this point in the history
closes #1139
  • Loading branch information
Foxandxss authored and wardbell committed Apr 23, 2016
1 parent 0e63b1f commit 4097c67
Show file tree
Hide file tree
Showing 5 changed files with 74 additions and 74 deletions.
28 changes: 14 additions & 14 deletions public/docs/_examples/template-syntax/dart/lib/app_component.html
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ <h1>Template Syntax</h1>
<a href="#local-vars">Template local variables</a><br>
<a href="#inputs-and-outputs">Inputs and outputs</a><br>
<a href="#pipes">Pipes</a><br>
<a href="#elvis">Elvis <i>?.</i></a><br>
<a href="#safe-navigation-operator">Safe navigation operator <i>?.</i></a><br>
<!--<a href="#enums">Enums</a><br>-->

<!-- Interpolation and expressions -->
Expand Down Expand Up @@ -738,25 +738,25 @@ <h4>Example Form</h4>

<a class="to-toc" href="#toc">top</a>

<!-- Null values and the Elvis operator -->
<hr><h2 id="elvis">Elvis <i>?.</i></h2>
<!-- Null values and the safe navigation operator -->
<hr><h2 id="safe-navigation-operator">Safe navigation operator <i>?.</i></h2>

<div>
<!-- #docregion elvis-1 -->
<!-- #docregion safe-1 -->
The title is {{ title }}
<!-- #enddocregion elvis-1 -->
<!-- #enddocregion safe-1 -->
</div>

<div>
<!-- #docregion elvis-2 -->
<!-- #docregion safe-2 -->
The current hero's name is {{currentHero?.firstName}}
<!-- #enddocregion elvis-2 -->
<!-- #enddocregion safe-2 -->
</div>

<div>
<!-- #docregion elvis-3 -->
<!-- #docregion safe-3 -->
The current hero's name is {{currentHero.firstName}}
<!-- #enddocregion elvis-3 -->
<!-- #enddocregion safe-3 -->
</div>


Expand All @@ -768,18 +768,18 @@ <h4>Example Form</h4>
EXCEPTION: The null object does not have a getter 'firstName'.
-->

<!-- #docregion elvis-4 -->
<!-- #docregion safe-4 -->
<!--No hero, div not displayed, no error -->
<div *ngIf="nullHero != null">The null hero's name is {{nullHero.firstName}}</div>
<!-- #enddocregion elvis-4 -->
<!-- #enddocregion safe-4 -->

<!-- skip docregion elvis-5 -->
<!-- skip docregion safe-5 -->

<div>
<!-- #docregion elvis-6 -->
<!-- #docregion safe-6 -->
<!-- No hero, no problem! -->
The null hero's name is {{nullHero?.firstName}}
<!-- #enddocregion elvis-6 -->
<!-- #enddocregion safe-6 -->
</div>


Expand Down
30 changes: 15 additions & 15 deletions public/docs/_examples/template-syntax/ts/app/app.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ <h1>Template Syntax</h1>
<a href="#local-vars">Template local variables</a><br>
<a href="#inputs-and-outputs">Inputs and outputs</a><br>
<a href="#pipes">Pipes</a><br>
<a href="#elvis">Elvis <i>?.</i></a><br>
<a href="#safe-navigation-operator">Safe navigation operator <i>?.</i></a><br>
<a href="#enums">Enums</a><br>

<!-- Interpolation and expressions -->
Expand Down Expand Up @@ -739,25 +739,25 @@ <h4>Example Form</h4>

<a class="to-toc" href="#toc">top</a>

<!-- Null values and the Elvis operator -->
<hr><h2 id="elvis">Elvis <i>?.</i></h2>
<!-- Null values and the safe navigation operator -->
<hr><h2 id="safe-navigation-operator">Safe navigation operator <i>?.</i></h2>

<div>
<!-- #docregion elvis-1 -->
<!-- #docregion safe-1 -->
The title is {{ title }}
<!-- #enddocregion elvis-1 -->
<!-- #enddocregion safe-1 -->
</div>

<div>
<!-- #docregion elvis-2 -->
<!-- #docregion safe-2 -->
The current hero's name is {{currentHero?.firstName}}
<!-- #enddocregion elvis-2 -->
<!-- #enddocregion safe-2 -->
</div>

<div>
<!-- #docregion elvis-3 -->
<!-- #docregion safe-3 -->
The current hero's name is {{currentHero.firstName}}
<!-- #enddocregion elvis-3 -->
<!-- #enddocregion safe-3 -->
</div>


Expand All @@ -768,22 +768,22 @@ <h4>Example Form</h4>
TypeError: Cannot read property 'firstName' of null in [null]
-->

<!-- #docregion elvis-4 -->
<!-- #docregion safe-4 -->
<!--No hero, div not displayed, no error -->
<div *ngIf="nullHero">The null hero's name is {{nullHero.firstName}}</div>
<!-- #enddocregion elvis-4 -->
<!-- #enddocregion safe-4 -->

<div>
<!-- #docregion elvis-5 -->
<!-- #docregion safe-5 -->
The null hero's name is {{nullHero && nullHero.firstName}}
<!-- #enddocregion elvis-5 -->
<!-- #enddocregion safe-5 -->
</div>

<div>
<!-- #docregion elvis-6 -->
<!-- #docregion safe-6 -->
<!-- No hero, no problem! -->
The null hero's name is {{nullHero?.firstName}}
<!-- #enddocregion elvis-6 -->
<!-- #enddocregion safe-6 -->
</div>


Expand Down
30 changes: 15 additions & 15 deletions public/docs/dart/latest/guide/template-syntax.jade
Original file line number Diff line number Diff line change
Expand Up @@ -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')
Expand All @@ -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')
58 changes: 29 additions & 29 deletions public/docs/ts/latest/guide/template-syntax.jade
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
<a id="elvis"></a>
### The Elvis operator ( ?. ) and null property paths
<a id="safe-navigation-operator"></a>
### The safe navigation operator ( ?. ) and null property paths

The Angular **Elvis operator (`?.`)** &mdash; perhaps better described as the "safe navigation operator" &mdash; 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.
Expand All @@ -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*.

Expand All @@ -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
Expand Down
2 changes: 1 addition & 1 deletion public/docs/ts/latest/guide/upgrade.jade
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit 4097c67

Please sign in to comment.