In the hero.service.ts
file for Angular's quick start example, step 7, is this snippet of code:
@Injectable()
export class HeroService {
private headers = new Headers({'Content-Type': 'application/json'});
private heroesUrl = 'api/heroes'; // URL to web api
constructor(private http: Http) { }
getHeroes(): Promise<Hero[]> {
return this.http.get(this.heroesUrl)
.toPromise()
.then(response => response.json().data as Hero[])
.catch(this.handleError);
}
}
I tried to translate it into my app like this:
@Injectable()
export class MyService {
private headers = new Headers({'Content-Type': 'application/json'});
private dataUrl = 'api/data'; // URL to web api
constructor(private http: Http) { }
getHeroes(): Promise<Hero[]> {
return this.http.get(this.dataUrl) // <-- error here
.toPromise()
.then(response => response.json().data as MyData[])
.catch(this.handleError);
}
}
I got a 404 - Collection
datanot found
on the this.http.get
line, which is completely understandable since it's just a random path. There's no API at that endpoint.
Question: how did the Angular example work? Where did it register the api/heroes
path for mock HTTP requests?
When using Angular's regular HTTP module, the command:
expects
this.dataUrl
to be a string containing the address of a real HTTP web service. (Such as"http://swapi.co/api/people/1/"
.)In "regular use", that command will make a request to the HTTP service at
this.dataUrl
.But... your code is taken from the tutorial, which changes things a bit.
If you would recall, the tutorial asked for you to add the
InMemoryWebApiModule
to your@NgModule
:Those lines you add create a service that, roughly speaking, hijacks your http requests, preventing them from reaching the real server of the URL you give (say
myserver.com/api/heroes
), but instead making those requests go to a fake server.(For details, notice that
InMemoryWebApiModule
comes fromangular-in-memory-web-api
. So check https://github.com/angular/in-memory-web-api to understand how it works.)Now, that fake server has to return some data to be useful. Where does it come from?
This is where the "second part" of
InMemoryWebApiModule.forRoot(InMemoryDataService)
, namelyInMemoryDataService
, comes into play.At the demo from Angular docs notice that
InMemoryDataService
is defined at'./in-memory-data.service'
:Now, the important part here is the returning command
return {heroes};
. (If you are unfamiliar with the syntax, that is short forreturn {heroes: heroes};
).The keys of that returned object define the available URLs at the fake server.
Since you are returning
{heroes: <something>}
, the URLapi/heroes
will be available at the fake server. If you returned{foo: <something>}
, then the URLapi/foo
would be available.As you want
api/data
to be available, then return something like{data: ...}
would do:So that's it, that's what you need to change.
Now, keep in mind that, for production (real) code, you should remove that whole
InMemoryWebApiModule.forRoot(InMemoryDataService)
thing and have a real web service responding atthis.dataUrl
.