Skip to content

Commit 0df6f61

Browse files
committed
Adding HeroesComponent, HttpErrorHandlerService and MessageService
GET-request implementation
1 parent 46585e6 commit 0df6f61

File tree

10 files changed

+229
-4
lines changed

10 files changed

+229
-4
lines changed

src/app/app.component.html

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,7 @@
11
<h1>HTTP Sample</h1>
2+
<div>
3+
<input type="checkbox" id="heroes" [checked]="showHeroes" (click)="toggleHeroes()" />
4+
<label for="heroes">Heroes</label>
5+
</div>
6+
7+
<app-heroes *ngIf="showHeroes"></app-heroes>

src/app/app.component.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,14 @@
11
import { Component } from '@angular/core';
22

33
@Component({
4-
selector: 'app-root',
5-
templateUrl: './app.component.html',
6-
styleUrls: ['./app.component.css']
4+
selector: 'app-root',
5+
templateUrl: './app.component.html',
6+
styleUrls: ['./app.component.css'],
77
})
88
export class AppComponent {
9+
public showHeroes = true;
10+
11+
public toggleHeroes(): void {
12+
this.showHeroes = !this.showHeroes;
13+
}
914
}

src/app/app.module.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@ import { FormsModule } from '@angular/forms';
44
import { HeroesComponent } from './heroes/heroes.component';
55
import { HttpClientInMemoryWebApiModule } from 'angular-in-memory-web-api';
66
import { HttpClientModule } from '@angular/common/http';
7+
import { HttpErrorHandler } from './http-error-handler.service';
78
import { InMemoryDataService } from './in-memory-data.service';
9+
import { MessageService } from './messages/message.service';
810
import { NgModule } from '@angular/core';
911

1012
@NgModule({
@@ -19,7 +21,7 @@ import { NgModule } from '@angular/core';
1921
put204: false,
2022
}),
2123
],
22-
providers: [],
24+
providers: [HttpErrorHandler, MessageService],
2325
bootstrap: [AppComponent],
2426
})
2527
export class AppModule {}

src/app/heroes/hero.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
export interface Hero {
2+
id: number;
3+
name: string;
4+
}
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
/* HeroesComponent's private CSS styles */
2+
.heroes {
3+
margin: 0 0 2em 0;
4+
list-style-type: none;
5+
padding: 0;
6+
width: 15em;
7+
}
8+
.heroes li {
9+
position: relative;
10+
cursor: pointer;
11+
background-color: #eee;
12+
margin: 0.5em;
13+
padding: 0.3em 0;
14+
height: 1.6em;
15+
border-radius: 4px;
16+
width: 19em;
17+
}
18+
19+
.heroes li:hover {
20+
color: #607d8b;
21+
background-color: #ddd;
22+
left: 0.1em;
23+
}
24+
25+
.heroes a {
26+
color: #888;
27+
text-decoration: none;
28+
position: relative;
29+
display: block;
30+
width: 250px;
31+
}
32+
33+
.heroes a:hover {
34+
color: #607d8b;
35+
}
36+
37+
.heroes .badge {
38+
display: inline-block;
39+
font-size: small;
40+
color: white;
41+
padding: 0.8em 0.7em 0 0.7em;
42+
background-color: #607d8b;
43+
line-height: 1em;
44+
position: relative;
45+
left: -1px;
46+
top: -4px;
47+
height: 1.8em;
48+
min-width: 16px;
49+
text-align: right;
50+
margin-right: 0.8em;
51+
border-radius: 4px 0 0 4px;
52+
}
53+
54+
.button {
55+
background-color: #eee;
56+
border: none;
57+
padding: 5px 10px;
58+
border-radius: 4px;
59+
cursor: pointer;
60+
cursor: hand;
61+
font-family: Arial;
62+
}
63+
64+
button:hover {
65+
background-color: #cfd8dc;
66+
}
67+
68+
button.delete {
69+
position: relative;
70+
left: 24em;
71+
top: -32px;
72+
background-color: gray !important;
73+
color: white;
74+
display: inherit;
75+
padding: 5px 8px;
76+
width: 2em;
77+
}
78+
79+
input {
80+
font-size: 100%;
81+
margin-bottom: 2px;
82+
width: 11em;
83+
}
84+
85+
.heroes input {
86+
position: relative;
87+
top: -3px;
88+
width: 12em;
89+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<h3>Heroes</h3>
2+
3+
<ul class="heroes">
4+
<li *ngFor="let hero of heroes">
5+
<a (click)="edit(hero)">
6+
<span class="badge">{{ hero.id || -1 }}</span>
7+
<span *ngIf="hero !== editHero">{{ hero.name }}</span>
8+
</a>
9+
</li>
10+
</ul>

src/app/heroes/heroes.component.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import { Component, OnInit } from '@angular/core';
2+
import { Hero } from './hero';
3+
import { HeroesService } from './heroes.service';
4+
5+
@Component({
6+
selector: 'app-heroes',
7+
templateUrl: './heroes.component.html',
8+
providers: [HeroesService],
9+
styleUrls: ['./heroes.component.css'],
10+
})
11+
export class HeroesComponent implements OnInit {
12+
public editHero: Hero;
13+
public heroes: Hero[];
14+
15+
constructor(private heroesService: HeroesService) {}
16+
17+
public ngOnInit(): void {
18+
this.getHeroes();
19+
}
20+
21+
public getHeroes(): void {
22+
this.heroesService.getHeroes().subscribe(heroes => (this.heroes = heroes));
23+
}
24+
25+
public edit(hero: Hero): void {
26+
this.editHero = hero;
27+
}
28+
}

src/app/heroes/heroes.service.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import { catchError } from 'rxjs/operators';
2+
import { Hero } from './hero';
3+
import { HttpClient, HttpHeaders } from '@angular/common/http';
4+
import { HandleError, HttpErrorHandler } from '../http-error-handler.service';
5+
import { Injectable } from '@angular/core';
6+
import { Observable } from 'rxjs';
7+
8+
const httpOptions = {
9+
headers: new HttpHeaders({
10+
'Content-Type': 'application/json',
11+
Authorization: 'my-auth-token',
12+
}),
13+
};
14+
15+
@Injectable()
16+
export class HeroesService {
17+
private handleError: HandleError;
18+
private readonly heroesUrl = 'api/heroesList';
19+
20+
constructor(private http: HttpClient, httpErrorHandler: HttpErrorHandler) {
21+
this.handleError = httpErrorHandler.createHandleError('HeroesService');
22+
}
23+
24+
public getHeroes(): Observable<Hero[]> {
25+
return this.http
26+
.get<Hero[]>(this.heroesUrl)
27+
.pipe(catchError(this.handleError('getHeroes', [])));
28+
}
29+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import { HttpErrorResponse } from '@angular/common/http';
2+
import { Injectable } from '@angular/core';
3+
import { MessageService } from './messages/message.service';
4+
import { Observable, of } from 'rxjs';
5+
6+
export type HandleError = <T>(
7+
operation?: string,
8+
result?: T,
9+
) => (error: HttpErrorResponse) => Observable<T>;
10+
11+
@Injectable()
12+
export class HttpErrorHandler {
13+
constructor(private messageService: MessageService) {}
14+
15+
createHandleError = (serviceName = '') => <T>(operation = 'operation', result = {} as T) =>
16+
this.handleError(serviceName, operation, result);
17+
18+
/**
19+
* Returns a function that handles Http operation failures.
20+
* This error handler lets the app continue to run as if no error occurred.
21+
* @param serviceName = name of the data service that attempted the operation
22+
* @param operation - name of the operation that failed
23+
* @param result - optional value to return as the observable result
24+
*/
25+
handleError<T>(serviceName = '', operation = 'operation', result = {} as T) {
26+
return (error: HttpErrorResponse): Observable<T> => {
27+
console.error(error);
28+
29+
const message =
30+
error.error instanceof ErrorEvent
31+
? error.error.message
32+
: `server returned code ${error.status} with body "${error.error}"`;
33+
this.messageService.add(`${serviceName}: ${operation} failed: ${message}`);
34+
35+
return of(result);
36+
};
37+
}
38+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import { Injectable } from '@angular/core';
2+
3+
@Injectable()
4+
export class MessageService {
5+
public messages: string[] = [];
6+
7+
public add(message: string): void {
8+
this.messages.push(message);
9+
}
10+
11+
public clear(): void {
12+
this.messages = [];
13+
}
14+
}

0 commit comments

Comments
 (0)