-
Notifications
You must be signed in to change notification settings - Fork 0
Angular Tutorial: Tour of Heroes
Angular has provided an excellent tutorial application to help you get up and running quickly: the Tour Of Heroes application. Divided into several parts, it covers some of the core functionality of the Angular framework. Spending some time following it is highly recommend.
Find the tutorial at https://angular.io/tutorial - It is divided up into 8 parts, which you will see on the left-hand side of the page.
There were a few typographical errors and unclear items that I found while running through the tutorial, and to help you along, these are now documented below. Make sure you look at the sections below for the corresponding part you are working on, so as to not run into anything that will trip you up!
Note: To install the Angular CLI tool, you first install Node.js, and then running the following command in a command line/terminal window:
npm install -g @angular/cli
This subsection asks you to: Add a hero
property to the HeroesComponent
for a hero named "Windstorm."
There are several places in the tutorial that ask you to add a property to a component. These properties should appear inside the class, that you find in the component.ts file in question, near the top. In this example, it should look like this
heroes.component.ts (hero property):
export class HeroesComponent implements OnInit {
hero = 'Windstorm';
In this subsection, you are asked to: Open the AppModule
class, import the HeroService
, and add it to the @NgModule.providers
array.
src/app/app.module.ts (providers):
providers: [ HeroService, MessageService ],
Note, that MessageService
is here in the providers
list. If you try and run the application at this point, it will crash with an error. This is because you have not yet created the MessageService
. Instead, the providers
list should simply look like this:
src/app/app.module.ts (providers):
providers: [ HeroService ],
Once you create the MessageService
later in the tutorial, come back here and add it to the providers
list.
In this subsection, you are asked to: Then define an array of routes with a single route to that component.
app-routing.module.ts:
import { HeroesComponent } from './heroes/heroes.component';
const routes: Routes = [
{ path: 'heroes', component: HeroesComponent }
];
Just note that here, you are defining a constant property called routes
. Unlike other properties you have created in the tutorial up until now, a constant cannot be created inside a class - you can see above that it appears right under the list of import
statements. You can then use it inside the class.
In this subsection, you are asked to: Import the InMemoryWebApiModule
and the InMemoryDataService
class, which you will create in a moment.
src/app/app.module.ts (In-memory Web API imports):
import { HttpClientInMemoryWebApiModule } from 'angular-in-memory-web-api';
import { InMemoryDataService } from './in-memory-data.service';
Add the InMemoryWebApiModule
to the @NgModule.imports
array— after importing the HttpClient, —while configuring it with the InMemoryDataService.
HttpClientModule,
// The HttpClientInMemoryWebApiModule module intercepts HTTP requests
// and returns simulated server responses.
// Remove it when a real server is ready to receive requests.
HttpClientInMemoryWebApiModule.forRoot(
InMemoryDataService, { dataEncapsulation: false }
)
I got a little confused here, and tried to import { HttpClient } from '@angular/common/http'
, but this is not correct, even though it shows no error. You need to import HttpClientModule from @angular/common/http
. The imports section of the code should contain these new additional imports as a result of walking through this subsection (leaving out here all the other previous imports from the extract below!):
src/app/app.module.ts:
import { HttpClientModule } from '@angular/common/http'
import { HttpClientInMemoryWebApiModule } from 'angular-in-memory-web-api';
import { InMemoryDataService } from './in-memory-data.service';
Furthermore, when you are done with the above, the @NgModule
block should look like this:
@NgModule({
declarations: [
AppComponent,
HeroesComponent,
HeroDetailComponent,
MessagesComponent,
DashboardComponent
],
imports: [
BrowserModule,
FormsModule,
AppRoutingModule,
HttpClientModule,
// The HttpClientInMemoryWebApiModule module intercepts HTTP requests
// and returns simulated server responses.
// Remove it when a real server is ready to receive requests.
HttpClientInMemoryWebApiModule.forRoot(
InMemoryDataService, { dataEncapsulation: false })
],
providers: [ HeroService, MessageService],
bootstrap: [AppComponent]
})
The big block of code in this subsection (handleError<T>()
function/method) should go inside the HeroService
class in hero.service.ts
.
The big block of searchTerms.pipe()
code in this subsection, must go inside the HeroSearchComponent
class in hero-search.component.ts
, specifically inside the ngOnInit()
function/method. The class inside this file will look like this:
export class HeroSearchComponent implements OnInit {
heroes$: Observable<Hero[]>;
private searchTerms = new Subject<string>();
constructor(private heroService: HeroService) {}
// Push a search term into the observable stream.
search(term: string): void {
this.searchTerms.next(term);
}
ngOnInit(): void {
this.heroes$ = this.searchTerms.pipe(
// wait 300ms after each keystroke before considering the term
debounceTime(300),
// ignore new term if same as previous term
distinctUntilChanged(),
// switch to new search observable each time the term changes
switchMap((term: string) => this.heroService.searchHeroes(term)),
);
}
}