Reputation: 407
I am trying to learn angular2 (coming from php scripts, it is quite difficult^^), using a real rest api in "Tour of Heroes". From what I read, I thought it could be simple...
I have a working api, built with Express :
curl -XGET http://localhost:3001/heroes
[{"_id":"58185c8a8af4b512c51c0519","no":"1","name":"bahamut","__v":0,"updated_at":"2016-11-01T09:12:42.803Z"},{"_id":"58185ca78af4b512c51c051a","no":"2","name":"gatz","__v":0,"updated_at":"2016-11-01T09:13:11.063Z"},{"_id":"58185ec98af4b512c51c051b","no":"3","nam...
In hero.service.ts, I can get the data :
getHeroes(): Promise<Hero[]> { // {{{
console.log('getheroes in service');
console.log( "%o", this.http.get(this.heroesUrl).toPromise());
return this.http.get(this.heroesUrl)
.toPromise()
.then(response => response.json().data as Hero[])
.catch(this.handleError);
} // }}}
When I do same console.log on original "Tour of Heroes", I have an array in data whereas here I have a string... I guess I have to convert somewhere the string but whatever I tried, it does not work.
(I read many examples with Observable too but I have not succeeded either)
Help wanted to explain me how to... TIA
JP
Upvotes: 1
Views: 105
Reputation: 1028
You're so close! The mistake here is in how you handle Promises, along with misunderstanding how they return. In this case you were trying to assign an undefined property (response.json().data
) when you meant to coerce response.json()
as type Hero[]
then return.
What you'll need to do is ensure you have a matching type to assign your response when it's converted to a JSON with that json()
call. The Hero
type in the guide does not match your response, and you'll have errors because of that.
To check that you're receiving a response, make a call to the service's getHeroes()
function and log the returned value. Logging internally to the function can be done, but that would be where understanding how Promises work in depth would help more than anything.
getHeroes(): Promise<Hero[]> {
return this.http.get(this.heroesUrl)
.toPromise()
.then((response) => response.json() as Hero[])
.catch(this.handleError);
}
If you want to know I'm not crazy, here's the code to log internally. This should log your response no matter what type is received.
getHeroes(): Promise<Hero[]> {
return this.http.get(this.heroesUrl)
.toPromise()
.then((response) => {
console.log(response.json());
})
.catch(this.handleError);
}
For further context into why you do these then()
calls, a Promise returns asynchronously which means the result is only available after an indeterminate amount of time has passed. Any execution that must wait for the result must either happen in the then()
calls or after the function returns an actual value. As JS functions run synchronously if you try to execute the following example you'll see a printout of undefined
rather than a string response. This is because the console.log(r)
is called immediately after the promise call, completely oblivious to the fact it hasn't actually let r
be assigned a value.
getHeroes(): Promise<Hero[]> {
var r;
this.http.get(this.heroesUrl)
.toPromise()
.then((response) => r = response.json())
.catch(this.handleError);
console.log(r);
}
Upvotes: 1