parent
596dfb88a6
commit
edd26a2b79
|
@ -53,7 +53,7 @@ describe('Tutorial part 6', () => {
|
||||||
|
|
||||||
appDashboardHref: navElts.get(0),
|
appDashboardHref: navElts.get(0),
|
||||||
appDashboard: element(by.css('app-root app-dashboard')),
|
appDashboard: element(by.css('app-root app-dashboard')),
|
||||||
topHeroes: element.all(by.css('app-root app-dashboard > div h4')),
|
topHeroes: element.all(by.css('app-root app-dashboard > div a')),
|
||||||
|
|
||||||
appHeroesHref: navElts.get(1),
|
appHeroesHref: navElts.get(1),
|
||||||
appHeroes: element(by.css('app-root app-heroes')),
|
appHeroes: element(by.css('app-root app-heroes')),
|
||||||
|
@ -176,7 +176,7 @@ describe('Tutorial part 6', () => {
|
||||||
const numHeroes = heroesBefore.length;
|
const numHeroes = heroesBefore.length;
|
||||||
|
|
||||||
await element(by.css('input')).sendKeys(addedHeroName);
|
await element(by.css('input')).sendKeys(addedHeroName);
|
||||||
await element(by.buttonText('add')).click();
|
await element(by.buttonText('Add hero')).click();
|
||||||
|
|
||||||
const page = getPageElts();
|
const page = getPageElts();
|
||||||
const heroesAfter = await toHeroArray(page.allHeroes);
|
const heroesAfter = await toHeroArray(page.allHeroes);
|
||||||
|
@ -195,18 +195,18 @@ describe('Tutorial part 6', () => {
|
||||||
// Inherited styles from styles.css
|
// Inherited styles from styles.css
|
||||||
expect(await button.getCssValue('font-family')).toBe('Arial, sans-serif');
|
expect(await button.getCssValue('font-family')).toBe('Arial, sans-serif');
|
||||||
expect(await button.getCssValue('border')).toContain('none');
|
expect(await button.getCssValue('border')).toContain('none');
|
||||||
expect(await button.getCssValue('padding')).toBe('5px 10px');
|
expect(await button.getCssValue('padding')).toBe('1px 10px 3px');
|
||||||
expect(await button.getCssValue('border-radius')).toBe('4px');
|
expect(await button.getCssValue('border-radius')).toBe('4px');
|
||||||
// Styles defined in heroes.component.css
|
// Styles defined in heroes.component.css
|
||||||
expect(await button.getCssValue('left')).toBe('194px');
|
expect(await button.getCssValue('left')).toBe('210px');
|
||||||
expect(await button.getCssValue('top')).toBe('-32px');
|
expect(await button.getCssValue('top')).toBe('5px');
|
||||||
}
|
}
|
||||||
|
|
||||||
const addButton = element(by.buttonText('add'));
|
const addButton = element(by.buttonText('Add hero'));
|
||||||
// Inherited styles from styles.css
|
// Inherited styles from styles.css
|
||||||
expect(await addButton.getCssValue('font-family')).toBe('Arial, sans-serif');
|
expect(await addButton.getCssValue('font-family')).toBe('Arial, sans-serif');
|
||||||
expect(await addButton.getCssValue('border')).toContain('none');
|
expect(await addButton.getCssValue('border')).toContain('none');
|
||||||
expect(await addButton.getCssValue('padding')).toBe('5px 10px');
|
expect(await addButton.getCssValue('padding')).toBe('8px 24px');
|
||||||
expect(await addButton.getCssValue('border-radius')).toBe('4px');
|
expect(await addButton.getCssValue('border-radius')).toBe('4px');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -1,23 +1,20 @@
|
||||||
/* AppComponent's private CSS styles */
|
/* AppComponent's private CSS styles */
|
||||||
h1 {
|
h1 {
|
||||||
font-size: 1.2em;
|
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
}
|
}
|
||||||
nav a {
|
nav a {
|
||||||
padding: 5px 10px;
|
padding: 1rem;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
margin-top: 10px;
|
margin-top: 10px;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
background-color: #eee;
|
background-color: #e8e8e8;
|
||||||
|
color: #3d3d3d;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
}
|
}
|
||||||
nav a:visited, a:link {
|
|
||||||
color: #334953;
|
|
||||||
}
|
|
||||||
nav a:hover {
|
nav a:hover {
|
||||||
color: #039be5;
|
color: white;
|
||||||
background-color: #CFD8DC;
|
background-color: #42545C;
|
||||||
}
|
}
|
||||||
nav a.active {
|
nav a.active {
|
||||||
color: #039be5;
|
background-color: black;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,61 +1,54 @@
|
||||||
/* DashboardComponent's private CSS styles */
|
/* DashboardComponent's private CSS styles */
|
||||||
[class*='col-'] {
|
|
||||||
float: left;
|
h2 {
|
||||||
padding-right: 20px;
|
text-align: center;
|
||||||
padding-bottom: 20px;
|
|
||||||
}
|
}
|
||||||
[class*='col-']:last-of-type {
|
|
||||||
padding-right: 0;
|
.heroes-menu {
|
||||||
|
padding: 0;
|
||||||
|
margin: auto;
|
||||||
|
max-width: 1000px;
|
||||||
|
|
||||||
|
/* flexbox */
|
||||||
|
display: -webkit-box;
|
||||||
|
display: -moz-box;
|
||||||
|
display: -ms-flexbox;
|
||||||
|
display: -webkit-flex;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
justify-content: space-around;
|
||||||
|
align-content: flex-start;
|
||||||
|
align-items: flex-start;
|
||||||
}
|
}
|
||||||
|
|
||||||
a {
|
a {
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
*, *::after, *::before {
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
h3 {
|
|
||||||
text-align: center;
|
|
||||||
margin-bottom: 0;
|
|
||||||
}
|
|
||||||
h4 {
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
.grid {
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
.col-1-4 {
|
|
||||||
width: 25%;
|
|
||||||
}
|
|
||||||
.module {
|
|
||||||
padding: 20px;
|
|
||||||
text-align: center;
|
|
||||||
color: #eee;
|
|
||||||
max-height: 120px;
|
|
||||||
min-width: 120px;
|
|
||||||
background-color: #3f525c;
|
background-color: #3f525c;
|
||||||
border-radius: 2px;
|
border-radius: 2px;
|
||||||
|
padding: 1rem;
|
||||||
|
font-size: 1.2rem;
|
||||||
|
text-decoration: none;
|
||||||
|
display: inline-block;
|
||||||
|
color: #fff;
|
||||||
|
text-align: center;
|
||||||
|
width: 100%;
|
||||||
|
min-width: 70px;
|
||||||
|
margin: .5rem auto;
|
||||||
|
box-sizing: border-box;
|
||||||
|
|
||||||
|
/* flexbox */
|
||||||
|
order: 0;
|
||||||
|
flex: 0 1 auto;
|
||||||
|
align-self: auto;
|
||||||
}
|
}
|
||||||
.module:hover {
|
|
||||||
background-color: #EEE;
|
@media (min-width: 600px) {
|
||||||
cursor: pointer;
|
a {
|
||||||
color: #607d8b;
|
width: 18%;
|
||||||
}
|
box-sizing: content-box;
|
||||||
.grid-pad {
|
|
||||||
padding: 10px 0;
|
|
||||||
}
|
|
||||||
.grid-pad > [class*='col-']:last-of-type {
|
|
||||||
padding-right: 20px;
|
|
||||||
}
|
|
||||||
@media (max-width: 600px) {
|
|
||||||
.module {
|
|
||||||
font-size: 10px;
|
|
||||||
max-height: 75px; }
|
|
||||||
}
|
|
||||||
@media (max-width: 1024px) {
|
|
||||||
.grid {
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
.module {
|
|
||||||
min-width: 60px;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
a:hover {
|
||||||
|
background-color: black;
|
||||||
|
}
|
||||||
|
|
|
@ -1,10 +1,8 @@
|
||||||
<h3>Top Heroes</h3>
|
<h2>Top Heroes</h2>
|
||||||
<div class="grid grid-pad">
|
<div class="heroes-menu">
|
||||||
<a *ngFor="let hero of heroes" class="col-1-4"
|
<a *ngFor="let hero of heroes"
|
||||||
routerLink="/detail/{{hero.id}}">
|
routerLink="/detail/{{hero.id}}">
|
||||||
<div class="module hero">
|
{{hero.name}}
|
||||||
<h4>{{hero.name}}</h4>
|
|
||||||
</div>
|
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -37,7 +37,7 @@ describe('DashboardComponent', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should display "Top Heroes" as headline', () => {
|
it('should display "Top Heroes" as headline', () => {
|
||||||
expect(fixture.nativeElement.querySelector('h3').textContent).toEqual('Top Heroes');
|
expect(fixture.nativeElement.querySelector('h2').textContent).toEqual('Top Heroes');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should call heroService', waitForAsync(() => {
|
it('should call heroService', waitForAsync(() => {
|
||||||
|
|
|
@ -1,24 +1,19 @@
|
||||||
/* HeroDetailComponent's private CSS styles */
|
/* HeroDetailComponent's private CSS styles */
|
||||||
label {
|
label {
|
||||||
display: inline-block;
|
color: #435960;
|
||||||
width: 3em;
|
|
||||||
margin: .5em 0;
|
|
||||||
color: #607D8B;
|
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
input {
|
input {
|
||||||
height: 2em;
|
|
||||||
font-size: 1em;
|
font-size: 1em;
|
||||||
padding-left: .4em;
|
padding: .5rem;
|
||||||
}
|
}
|
||||||
button {
|
button {
|
||||||
margin-top: 20px;
|
margin-top: 20px;
|
||||||
font-family: Arial, sans-serif;
|
margin-right: .5rem;
|
||||||
background-color: #eee;
|
background-color: #eee;
|
||||||
border: none;
|
padding: 1rem;
|
||||||
padding: 5px 10px;
|
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
cursor: pointer;
|
font-size: 1rem;
|
||||||
}
|
}
|
||||||
button:hover {
|
button:hover {
|
||||||
background-color: #cfd8dc;
|
background-color: #cfd8dc;
|
||||||
|
|
|
@ -2,9 +2,8 @@
|
||||||
<h2>{{hero.name | uppercase}} Details</h2>
|
<h2>{{hero.name | uppercase}} Details</h2>
|
||||||
<div><span>id: </span>{{hero.id}}</div>
|
<div><span>id: </span>{{hero.id}}</div>
|
||||||
<div>
|
<div>
|
||||||
<label>name:
|
<label for="hero-name">Hero name: </label>
|
||||||
<input [(ngModel)]="hero.name" placeholder="name"/>
|
<input id="hero-name" [(ngModel)]="hero.name" placeholder="Hero name"/>
|
||||||
</label>
|
|
||||||
</div>
|
</div>
|
||||||
<button (click)="goBack()">go back</button>
|
<button (click)="goBack()">go back</button>
|
||||||
<!-- #docregion save -->
|
<!-- #docregion save -->
|
||||||
|
|
|
@ -1,37 +1,45 @@
|
||||||
/* HeroSearch private styles */
|
/* HeroSearch private styles */
|
||||||
.search-result li {
|
|
||||||
|
label {
|
||||||
|
display: block;
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 1.2rem;
|
||||||
|
margin-top: 1rem;
|
||||||
|
margin-bottom: .5rem;
|
||||||
|
|
||||||
|
}
|
||||||
|
input {
|
||||||
|
padding: .5rem;
|
||||||
|
width: 100%;
|
||||||
|
max-width: 600px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
input:focus {
|
||||||
|
outline: #336699 auto 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
li {
|
||||||
|
list-style-type: none;
|
||||||
|
}
|
||||||
|
.search-result li a {
|
||||||
border-bottom: 1px solid gray;
|
border-bottom: 1px solid gray;
|
||||||
border-left: 1px solid gray;
|
border-left: 1px solid gray;
|
||||||
border-right: 1px solid gray;
|
border-right: 1px solid gray;
|
||||||
width: 195px;
|
display: inline-block;
|
||||||
height: 16px;
|
width: 100%;
|
||||||
padding: 5px;
|
max-width: 600px;
|
||||||
background-color: white;
|
padding: .5rem;
|
||||||
cursor: pointer;
|
box-sizing: border-box;
|
||||||
list-style-type: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.search-result li:hover {
|
|
||||||
background-color: #607D8B;
|
|
||||||
}
|
|
||||||
|
|
||||||
.search-result li a {
|
|
||||||
color: #888;
|
|
||||||
display: block;
|
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
|
color: black;
|
||||||
}
|
}
|
||||||
|
|
||||||
.search-result li a:hover {
|
.search-result li a:hover {
|
||||||
|
background-color: #435A60;
|
||||||
color: white;
|
color: white;
|
||||||
}
|
}
|
||||||
.search-result li a:active {
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
#search-box {
|
|
||||||
width: 200px;
|
|
||||||
height: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ul.search-result {
|
ul.search-result {
|
||||||
margin-top: 0;
|
margin-top: 0;
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
<div id="search-component">
|
<div id="search-component">
|
||||||
<h4><label for="search-box">Hero Search</label></h4>
|
<label for="search-box">Hero Search</label>
|
||||||
|
|
||||||
<!-- #docregion input -->
|
<!-- #docregion input -->
|
||||||
<input #searchBox id="search-box" (input)="search(searchBox.value)" />
|
<input #searchBox id="search-box" (input)="search(searchBox.value)" />
|
||||||
<!-- #enddocregion input -->
|
<!-- #enddocregion input -->
|
||||||
|
|
|
@ -5,32 +5,44 @@
|
||||||
padding: 0;
|
padding: 0;
|
||||||
width: 15em;
|
width: 15em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
input {
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
padding: .5rem;
|
||||||
|
margin: 1rem 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
.heroes li {
|
.heroes li {
|
||||||
position: relative;
|
position: relative;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
background-color: #EEE;
|
|
||||||
margin: .5em;
|
|
||||||
padding: .3em 0;
|
|
||||||
height: 1.6em;
|
|
||||||
border-radius: 4px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.heroes li:hover {
|
.heroes li:hover {
|
||||||
color: #607D8B;
|
|
||||||
background-color: #DDD;
|
|
||||||
left: .1em;
|
left: .1em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.heroes a {
|
.heroes a {
|
||||||
color: #333;
|
color: #333;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
position: relative;
|
background-color: #EEE;
|
||||||
|
margin: .5em;
|
||||||
|
padding: .3em 0;
|
||||||
|
height: 1.6em;
|
||||||
|
border-radius: 4px;
|
||||||
display: block;
|
display: block;
|
||||||
width: 250px;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.heroes a:hover {
|
.heroes a:hover {
|
||||||
color: #607D8B;
|
color: #2c3a41;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.heroes a:active {
|
||||||
|
background-color: #525252;
|
||||||
|
color: #fafafa;
|
||||||
}
|
}
|
||||||
|
|
||||||
.heroes .badge {
|
.heroes .badge {
|
||||||
|
@ -38,7 +50,7 @@
|
||||||
font-size: small;
|
font-size: small;
|
||||||
color: white;
|
color: white;
|
||||||
padding: 0.8em 0.7em 0 0.7em;
|
padding: 0.8em 0.7em 0 0.7em;
|
||||||
background-color: #405061;
|
background-color:#405061;
|
||||||
line-height: 1em;
|
line-height: 1em;
|
||||||
position: relative;
|
position: relative;
|
||||||
left: -1px;
|
left: -1px;
|
||||||
|
@ -50,23 +62,28 @@
|
||||||
border-radius: 4px 0 0 4px;
|
border-radius: 4px 0 0 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
button {
|
.add-button {
|
||||||
background-color: #eee;
|
padding: .5rem 1.5rem;
|
||||||
border: none;
|
font-size: 1rem;
|
||||||
padding: 5px 10px;
|
margin-bottom: 2rem;
|
||||||
border-radius: 4px;
|
|
||||||
cursor: pointer;
|
|
||||||
font-family: Arial, sans-serif;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
button:hover {
|
.add-button:hover {
|
||||||
background-color: #cfd8dc;
|
color: white;
|
||||||
|
background-color: #42545C;
|
||||||
}
|
}
|
||||||
|
|
||||||
button.delete {
|
button.delete {
|
||||||
position: relative;
|
position: absolute;
|
||||||
left: 194px;
|
left: 210px;
|
||||||
top: -32px;
|
top: 5px;
|
||||||
background-color: gray !important;
|
background-color: white;
|
||||||
|
color: #525252;
|
||||||
|
font-size: 1.1rem;
|
||||||
|
padding: 1px 10px 3px 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
button.delete:hover {
|
||||||
|
background-color: #525252;
|
||||||
color: white;
|
color: white;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,12 +2,12 @@
|
||||||
|
|
||||||
<!-- #docregion add -->
|
<!-- #docregion add -->
|
||||||
<div>
|
<div>
|
||||||
<label>Hero name:
|
<label id="new-hero">Hero name: </label>
|
||||||
<input #heroName />
|
<input for="new-hero" #heroName />
|
||||||
</label>
|
|
||||||
<!-- (click) passes input value to add() and then clears the input -->
|
<!-- (click) passes input value to add() and then clears the input -->
|
||||||
<button (click)="add(heroName.value); heroName.value=''">
|
<button class="add-button" (click)="add(heroName.value); heroName.value=''">
|
||||||
add
|
Add hero
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<!-- #enddocregion add -->
|
<!-- #enddocregion add -->
|
||||||
|
|
|
@ -1,20 +1,19 @@
|
||||||
/* MessagesComponent's private CSS styles */
|
/* MessagesComponent's private CSS styles */
|
||||||
h2 {
|
h2 {
|
||||||
color: red;
|
color: #A80000;
|
||||||
font-family: Arial, Helvetica, sans-serif;
|
font-family: Arial, Helvetica, sans-serif;
|
||||||
font-weight: lighter;
|
font-weight: lighter;
|
||||||
}
|
}
|
||||||
|
|
||||||
button.clear {
|
.clear {
|
||||||
font-family: Arial, sans-serif;
|
|
||||||
color: #333;
|
color: #333;
|
||||||
background-color: #eee;
|
background-color: #eee;
|
||||||
margin-bottom: 12px;
|
margin-bottom: 12px;
|
||||||
border: none;
|
padding: 1rem;
|
||||||
padding: 5px 10px;
|
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
cursor: pointer;
|
font-size: 1rem;
|
||||||
}
|
}
|
||||||
button:hover {
|
.clear:hover {
|
||||||
background-color: #cfd8dc;
|
color: #fff;
|
||||||
|
background-color: #42545C;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
<h2>Messages</h2>
|
<h2>Messages</h2>
|
||||||
<button class="clear"
|
<button class="clear"
|
||||||
(click)="messageService.clear()">clear</button>
|
(click)="messageService.clear()">Clear messages</button>
|
||||||
<div *ngFor='let message of messageService.messages'> {{message}} </div>
|
<div *ngFor='let message of messageService.messages'> {{message}} </div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 11 KiB |
|
@ -9,7 +9,7 @@ Angular's `HttpClient`.
|
||||||
|
|
||||||
<div class="alert is-helpful">
|
<div class="alert is-helpful">
|
||||||
|
|
||||||
For the sample app that this page describes, see the <live-example></live-example>.
|
For the sample application that this page describes, see the <live-example></live-example>.
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@ Angular's `HttpClient`.
|
||||||
|
|
||||||
`HttpClient` is Angular's mechanism for communicating with a remote server over HTTP.
|
`HttpClient` is Angular's mechanism for communicating with a remote server over HTTP.
|
||||||
|
|
||||||
Make `HttpClient` available everywhere in the app in two steps. First, add it to the root `AppModule` by importing it:
|
Make `HttpClient` available everywhere in the application in two steps. First, add it to the root `AppModule` by importing it:
|
||||||
|
|
||||||
<code-example path="toh-pt6/src/app/app.module.ts" region="import-http-client" header="src/app/app.module.ts (HttpClientModule import)">
|
<code-example path="toh-pt6/src/app/app.module.ts" region="import-http-client" header="src/app/app.module.ts (HttpClientModule import)">
|
||||||
</code-example>
|
</code-example>
|
||||||
|
@ -33,7 +33,7 @@ Next, still in the `AppModule`, add `HttpClient` to the `imports` array:
|
||||||
This tutorial sample mimics communication with a remote data server by using the
|
This tutorial sample mimics communication with a remote data server by using the
|
||||||
[In-memory Web API](https://github.com/angular/angular/tree/master/packages/misc/angular-in-memory-web-api "In-memory Web API") module.
|
[In-memory Web API](https://github.com/angular/angular/tree/master/packages/misc/angular-in-memory-web-api "In-memory Web API") module.
|
||||||
|
|
||||||
After installing the module, the app will make requests to and receive responses from the `HttpClient`
|
After installing the module, the application will make requests to and receive responses from the `HttpClient`
|
||||||
without knowing that the *In-memory Web API* is intercepting those requests,
|
without knowing that the *In-memory Web API* is intercepting those requests,
|
||||||
applying them to an in-memory data store, and returning simulated responses.
|
applying them to an in-memory data store, and returning simulated responses.
|
||||||
|
|
||||||
|
@ -127,7 +127,7 @@ Convert that method to use `HttpClient` as follows:
|
||||||
Refresh the browser. The hero data should successfully load from the
|
Refresh the browser. The hero data should successfully load from the
|
||||||
mock server.
|
mock server.
|
||||||
|
|
||||||
You've swapped `of()` for `http.get()` and the app keeps working without any other changes
|
You've swapped `of()` for `http.get()` and the application keeps working without any other changes
|
||||||
because both functions return an `Observable<Hero[]>`.
|
because both functions return an `Observable<Hero[]>`.
|
||||||
|
|
||||||
### `HttpClient` methods return one value
|
### `HttpClient` methods return one value
|
||||||
|
@ -197,10 +197,10 @@ has configured with both the name of the operation that failed and a safe return
|
||||||
</code-example>
|
</code-example>
|
||||||
|
|
||||||
After reporting the error to the console, the handler constructs
|
After reporting the error to the console, the handler constructs
|
||||||
a user friendly message and returns a safe value to the app so the app can keep working.
|
a user friendly message and returns a safe value to the application so the application can keep working.
|
||||||
|
|
||||||
Because each service method returns a different kind of `Observable` result,
|
Because each service method returns a different kind of `Observable` result,
|
||||||
`handleError()` takes a type parameter so it can return the safe value as the type that the app expects.
|
`handleError()` takes a type parameter so it can return the safe value as the type that the application expects.
|
||||||
|
|
||||||
### Tap into the Observable
|
### Tap into the Observable
|
||||||
|
|
||||||
|
@ -283,7 +283,7 @@ The hero now appears in the list with the changed name.
|
||||||
|
|
||||||
## Add a new hero
|
## Add a new hero
|
||||||
|
|
||||||
To add a hero, this app only needs the hero's name. You can use an `<input>`
|
To add a hero, this application only needs the hero's name. You can use an `<input>`
|
||||||
element paired with an add button.
|
element paired with an add button.
|
||||||
|
|
||||||
Insert the following into the `HeroesComponent` template, just after
|
Insert the following into the `HeroesComponent` template, just after
|
||||||
|
@ -506,7 +506,7 @@ It cancels and discards previous search observables, returning only the latest s
|
||||||
|
|
||||||
Note that canceling a previous `searchHeroes()` Observable
|
Note that canceling a previous `searchHeroes()` Observable
|
||||||
doesn't actually abort a pending HTTP request.
|
doesn't actually abort a pending HTTP request.
|
||||||
Unwanted results are simply discarded before they reach your application code.
|
Unwanted results are discarded before they reach your application code.
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -515,11 +515,11 @@ That's the job of the [`AsyncPipe`](#asyncpipe) in the template.
|
||||||
|
|
||||||
#### Try it
|
#### Try it
|
||||||
|
|
||||||
Run the app again. In the *Dashboard*, enter some text in the search box.
|
Run the application again. In the *Dashboard*, enter some text in the search box.
|
||||||
If you enter characters that match any existing hero names, you'll see something like this.
|
If you enter characters that match any existing hero names, you'll see something like this.
|
||||||
|
|
||||||
<div class="lightbox">
|
<div class="lightbox">
|
||||||
<img src='generated/images/guide/toh/toh-hero-search.png' alt="Hero Search Component">
|
<img src='generated/images/guide/toh/toh-hero-search.gif' alt="Hero Search field with the letters 'm' and 'a' along with four search results that match the query displayed in a list beneath the search input">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
## Final code review
|
## Final code review
|
||||||
|
|
Loading…
Reference in New Issue