Reputation: 184
Stumped here. I must be missing something. I've followed the Angular tutorial up to part 6, which implements the HttpClientInMemoryWebApiModule, to mock the hero service backend. When I load the page, though, the console shows a 404 error contacting the url at api/heroes. Anyone have any idea what I've done wrong or how I can get past this?
app.module.ts:
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { HttpClientModule } from '@angular/common/http';
import { AppComponent } from './app.component';
import { HeroesComponent } from './heroes/heroes.component';
import { HeroDetailComponent } from './hero-detail/hero-detail.component';
import { MessagesComponent } from './messages/messages.component';
import { AppRoutingModule } from './app-routing.module';
import { DashboardComponent } from './dashboard/dashboard.component';
import { HttpClientInMemoryWebApiModule } from 'angular-in-memory-web-api';
import { InMemoryDataService } from './in-memory-data.service';
@NgModule({
declarations: [
AppComponent,
HeroesComponent,
HeroDetailComponent,
MessagesComponent,
DashboardComponent
],
imports: [
BrowserModule,
FormsModule,
HttpClientModule,
HttpClientInMemoryWebApiModule.forRoot(
InMemoryDataService, { dataEncapsulation: false }
),
AppRoutingModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
in-memory-data.service.ts:
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;
}
genId(heroes: Hero[]): number {
return heroes.length > 0 ? Math.max(...heroes.map(hero => hero.id)) + 1 : 11;
}
}
hero.service.ts:
import { Injectable } from '@angular/core';
import { Observable, of } from 'rxjs';
import { MessageService } from './message.service';
import { Hero } from './hero';
//import { HEROES } from './mock-heroes';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { catchError, map, tap } from 'rxjs/operators';
@Injectable({
providedIn: 'root'
})
export class HeroService {
private heroesUrl = 'api/heroes'; // URL to in-memory heroes resource
constructor(
private http: HttpClient,
private messageService: MessageService
) { }
getHeroes(): Observable<Hero[]> {
//this.log('HeroService: fetched heroes');
return this.http.get<Hero[]>(this.heroesUrl)
.pipe(
tap(_ => this.log('fetched heroes')),
catchError(this.handleError<Hero[]>('getHeroes', []))
);
}
getHero(id: number) : Observable<Hero> {
const url = `${this.heroesUrl}/${id}`;
return this.http.get<Hero>(url)
.pipe(
tap(_ => this.log(`fetched hero id=${id}`)),
catchError(this.handleError<Hero>(`getHero id=${id}`))
);
}
private log(message: string) {
this.messageService.add(`HeroService: ${message}`);
}
private handleError<T> (operation = 'operation', result?: T) {
return (error: any): Observable<T> => {
console.error(error);
this.log(`${operation} failed: ${error.message}`);
// Return empty result to let the app keep running
return of(result as T);
}
}
}
Upvotes: 1
Views: 701
Reputation: 184
Ah, death by the tiniest of mistakes!
In in-memory-data.service.ts, I fixed this by changing line 23 inside the createDb function:
return heroes;
to:
return { heroes };
Sigh. Time to drink more coffee and leave this answer here for posterity.
Upvotes: 1