Angular Tour of Heroes: WIP sur HTTP
This commit is contained in:
parent
9c0ec4282d
commit
81405d7daa
5
angular-tour-of-heroes/package-lock.json
generated
5
angular-tour-of-heroes/package-lock.json
generated
@ -2235,6 +2235,11 @@
|
|||||||
"integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=",
|
"integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"angular-in-memory-web-api": {
|
||||||
|
"version": "0.9.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/angular-in-memory-web-api/-/angular-in-memory-web-api-0.9.0.tgz",
|
||||||
|
"integrity": "sha512-//PiJ5qb1+Yf/N7270ioQqR2laf4/Irjavg+M+WEn8y4At9LUoYgbQ5HVwvM5xUTlVlL0XkbJRLxREcGGNdIEw=="
|
||||||
|
},
|
||||||
"ansi-colors": {
|
"ansi-colors": {
|
||||||
"version": "3.2.4",
|
"version": "3.2.4",
|
||||||
"resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.4.tgz",
|
"resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.4.tgz",
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
"@angular/platform-browser": "~8.2.9",
|
"@angular/platform-browser": "~8.2.9",
|
||||||
"@angular/platform-browser-dynamic": "~8.2.9",
|
"@angular/platform-browser-dynamic": "~8.2.9",
|
||||||
"@angular/router": "~8.2.9",
|
"@angular/router": "~8.2.9",
|
||||||
|
"angular-in-memory-web-api": "^0.9.0",
|
||||||
"rxjs": "~6.4.0",
|
"rxjs": "~6.4.0",
|
||||||
"tslib": "^1.10.0",
|
"tslib": "^1.10.0",
|
||||||
"zone.js": "~0.9.1"
|
"zone.js": "~0.9.1"
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import { BrowserModule } from '@angular/platform-browser';
|
import { BrowserModule } from '@angular/platform-browser';
|
||||||
import { NgModule } from '@angular/core';
|
import { NgModule } from '@angular/core';
|
||||||
import { FormsModule } from '@angular/forms'; // <-- NgModel lives here
|
import { FormsModule } from '@angular/forms'; // <-- NgModel lives here
|
||||||
|
import { HttpClientModule } from '@angular/common/http';
|
||||||
|
|
||||||
import { AppComponent } from './app.component';
|
import { AppComponent } from './app.component';
|
||||||
import { HeroesComponent } from './heroes/heroes.component';
|
import { HeroesComponent } from './heroes/heroes.component';
|
||||||
@ -9,6 +10,9 @@ import { MessagesComponent } from './messages/messages.component';
|
|||||||
import { AppRoutingModule } from './app-routing.module';
|
import { AppRoutingModule } from './app-routing.module';
|
||||||
import { DashboardComponent } from './dashboard/dashboard.component';
|
import { DashboardComponent } from './dashboard/dashboard.component';
|
||||||
|
|
||||||
|
import { HttpClientInMemoryWebApiModule } from 'angular-in-memory-web-api';
|
||||||
|
import { InMemoryDataService } from './in-memory-data.service';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [
|
declarations: [
|
||||||
AppComponent,
|
AppComponent,
|
||||||
@ -20,7 +24,11 @@ import { DashboardComponent } from './dashboard/dashboard.component';
|
|||||||
imports: [
|
imports: [
|
||||||
BrowserModule,
|
BrowserModule,
|
||||||
FormsModule,
|
FormsModule,
|
||||||
AppRoutingModule
|
AppRoutingModule,
|
||||||
|
HttpClientModule,
|
||||||
|
HttpClientInMemoryWebApiModule.forRoot(
|
||||||
|
InMemoryDataService, { dataEncapsulation: false }
|
||||||
|
)
|
||||||
],
|
],
|
||||||
providers: [],
|
providers: [],
|
||||||
bootstrap: [AppComponent]
|
bootstrap: [AppComponent]
|
||||||
|
@ -1,25 +1,58 @@
|
|||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
import { Hero } from './hero';
|
import { Hero } from './hero';
|
||||||
import { HEROES } from './mock-heroes';
|
|
||||||
import { Observable, of } from 'rxjs';
|
import { Observable, of } from 'rxjs';
|
||||||
import { MessageService } from './message.service';
|
import { MessageService } from './message.service';
|
||||||
|
import { HttpClient, HttpHeaders } from '@angular/common/http';
|
||||||
|
import { catchError, map, tap } from 'rxjs/operators';
|
||||||
|
|
||||||
@Injectable({
|
@Injectable({
|
||||||
providedIn: 'root'
|
providedIn: 'root'
|
||||||
})
|
})
|
||||||
export class HeroService {
|
export class HeroService {
|
||||||
|
|
||||||
constructor(private messageService: MessageService) { }
|
constructor(
|
||||||
|
private http: HttpClient,
|
||||||
|
private messageService: MessageService) { }
|
||||||
|
|
||||||
|
private log(message: string) {
|
||||||
|
this.messageService.add(`HeroService: ${message}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
private heroesUrl = 'api/heroes'; // URL to web api
|
||||||
|
|
||||||
getHeroes(): Observable<Hero[]> {
|
getHeroes(): Observable<Hero[]> {
|
||||||
// TODO: send the message _after_ fetching the heroes
|
return this.http.get<Hero[]>(this.heroesUrl)
|
||||||
this.messageService.add('HeroService: fetched heroes.')
|
.pipe(
|
||||||
return of(HEROES);
|
catchError(this.handleError<Hero[]>('getHeroes', []))
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** GET hero by id. Will 404 if id not found */
|
||||||
getHero(id: number): Observable<Hero> {
|
getHero(id: number): Observable<Hero> {
|
||||||
// TODO: send the message _after_ fetching the hero
|
const url = `${this.heroesUrl}/${id}`;
|
||||||
this.messageService.add(`HeroService: fetched hero id=${id}`);
|
return this.http.get<Hero>(url).pipe(
|
||||||
return of(HEROES.find(hero => hero.id === id));
|
tap(_ => this.log(`fetched hero id=${id}`)),
|
||||||
|
catchError(this.handleError<Hero>(`getHero id=${id}`))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle Http operation that failed.
|
||||||
|
* Let the app continue.
|
||||||
|
* @param operation - name of the operation that failed
|
||||||
|
* @param result - optional value to return as the observable result
|
||||||
|
*/
|
||||||
|
private handleError<T> (operation = 'operation', result?: T) {
|
||||||
|
return (error: any): Observable<T> => {
|
||||||
|
|
||||||
|
// TODO: send the error to remote logging infrastructure
|
||||||
|
console.error(error); // log to console instead
|
||||||
|
|
||||||
|
// TODO: better job of transforming error for user consumption
|
||||||
|
this.log(`${operation} failed: ${error.message}`);
|
||||||
|
|
||||||
|
// Let the app keep running by returning an empty result.
|
||||||
|
return of(result as T);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import { Component, OnInit } from '@angular/core';
|
import { Component, OnInit } from '@angular/core';
|
||||||
import { Hero } from '../hero';
|
import { Hero } from '../hero';
|
||||||
import { HEROES } from '../mock-heroes';
|
|
||||||
import { HeroService } from '../hero.service';
|
import { HeroService } from '../hero.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
|
@ -0,0 +1,12 @@
|
|||||||
|
import { TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { InMemoryDataService } from './in-memory-data.service';
|
||||||
|
|
||||||
|
describe('InMemoryDataService', () => {
|
||||||
|
beforeEach(() => TestBed.configureTestingModule({}));
|
||||||
|
|
||||||
|
it('should be created', () => {
|
||||||
|
const service: InMemoryDataService = TestBed.get(InMemoryDataService);
|
||||||
|
expect(service).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
33
angular-tour-of-heroes/src/app/in-memory-data.service.ts
Normal file
33
angular-tour-of-heroes/src/app/in-memory-data.service.ts
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
import { InMemoryDbService } from 'angular-in-memory-web-api';
|
||||||
|
import { Hero } from './hero';
|
||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
|
||||||
|
@Injectable({
|
||||||
|
providedIn: 'root',
|
||||||
|
})
|
||||||
|
export class InMemoryDataService implements InMemoryDbService {
|
||||||
|
createDb() {
|
||||||
|
const heroes = [
|
||||||
|
{ id: 11, name: 'Dr Nice' },
|
||||||
|
{ id: 12, name: 'Narco' },
|
||||||
|
{ id: 13, name: 'Bombasto' },
|
||||||
|
{ id: 14, name: 'Celeritas' },
|
||||||
|
{ id: 15, name: 'Magneta' },
|
||||||
|
{ id: 16, name: 'RubberMan' },
|
||||||
|
{ id: 17, name: 'Dynama' },
|
||||||
|
{ id: 18, name: 'Dr IQ' },
|
||||||
|
{ id: 19, name: 'Magma' },
|
||||||
|
{ id: 20, name: 'Tornado' }
|
||||||
|
];
|
||||||
|
return {heroes};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Overrides the genId method to ensure that a hero always has an id.
|
||||||
|
// If the heroes array is empty,
|
||||||
|
// the method below returns the initial number (11).
|
||||||
|
// if the heroes array is not empty, the method below returns the highest
|
||||||
|
// hero id + 1.
|
||||||
|
genId(heroes: Hero[]): number {
|
||||||
|
return heroes.length > 0 ? Math.max(...heroes.map(hero => hero.id)) + 1 : 11;
|
||||||
|
}
|
||||||
|
}
|
@ -1,14 +0,0 @@
|
|||||||
import { Hero } from './hero';
|
|
||||||
|
|
||||||
export const HEROES: Hero[] = [
|
|
||||||
{ id: 11, name: 'Dr Nice' },
|
|
||||||
{ id: 12, name: 'Narco' },
|
|
||||||
{ id: 13, name: 'Bombasto' },
|
|
||||||
{ id: 14, name: 'Celeritas' },
|
|
||||||
{ id: 15, name: 'Magneta' },
|
|
||||||
{ id: 16, name: 'RubberMan' },
|
|
||||||
{ id: 17, name: 'Dynama' },
|
|
||||||
{ id: 18, name: 'Dr IQ' },
|
|
||||||
{ id: 19, name: 'Magma' },
|
|
||||||
{ id: 20, name: 'Tornado' }
|
|
||||||
]
|
|
Loading…
Reference in New Issue
Block a user