docs(http): discuss headers for POST

This commit is contained in:
Ward Bell 2016-02-01 19:52:14 -08:00
parent 2976789794
commit f2051d9cf6
3 changed files with 47 additions and 7 deletions

View File

@ -4,6 +4,7 @@
// #docregion // #docregion
import {Injectable} from 'angular2/core'; import {Injectable} from 'angular2/core';
import {Http, Response} from 'angular2/http'; import {Http, Response} from 'angular2/http';
import {Headers, RequestOptions} from 'angular2/http';
import {Hero} from './hero'; import {Hero} from './hero';
@Injectable() @Injectable()
@ -16,11 +17,16 @@ export class HeroService {
getHeroes () { getHeroes () {
return this.http.get(this._heroesUrl) return this.http.get(this._heroesUrl)
.toPromise() .toPromise()
.then(res => <Hero[]> res.json().data, this.handleError); .then(res => <Hero[]> res.json().data, this.handleError)
.then(data => { console.log(data); return data; }); // eyeball results in the console
} }
addHero (name: string) : Promise<Hero> { addHero (name: string) : Promise<Hero> {
return this.http.post(this._heroesUrl, JSON.stringify({ name })) let body = JSON.stringify({ name });
let headers = new Headers({ 'Content-Type': 'application/json' });
let options = new RequestOptions({ headers: headers });
return this.http.post(this._heroesUrl, body, options)
.toPromise() .toPromise()
.then(res => <Hero> res.json().data) .then(res => <Hero> res.json().data)
.catch(this.handleError); .catch(this.handleError);

View File

@ -4,6 +4,11 @@
// #docregion v1 // #docregion v1
import {Injectable} from 'angular2/core'; import {Injectable} from 'angular2/core';
import {Http, Response} from 'angular2/http'; import {Http, Response} from 'angular2/http';
// #enddocregion v1
// #docregion import-request-options
import {Headers, RequestOptions} from 'angular2/http';
// #enddocregion import-request-options
// #docregion v1
import {Hero} from './hero'; import {Hero} from './hero';
import {Observable} from 'rxjs/Observable'; import {Observable} from 'rxjs/Observable';
@ -32,7 +37,14 @@ export class HeroService {
// #docregion addhero // #docregion addhero
addHero (name: string) : Observable<Hero> { addHero (name: string) : Observable<Hero> {
return this.http.post(this._heroesUrl, JSON.stringify({ name }))
let body = JSON.stringify({ name });
//#docregion headers
let headers = new Headers({ 'Content-Type': 'application/json' });
let options = new RequestOptions({ headers: headers });
return this.http.post(this._heroesUrl, body, options)
//#enddocregion headers
.map(res => <Hero> res.json().data) .map(res => <Hero> res.json().data)
.catch(this.handleError) .catch(this.handleError)
} }

View File

@ -11,6 +11,7 @@ include ../../../../_includes/_util-fns
[Error handling](#error-handling)<br> [Error handling](#error-handling)<br>
[Log results to console](#do)<br> [Log results to console](#do)<br>
[Send data to the server](#update)<br> [Send data to the server](#update)<br>
[Add headers](#headers)<br>
[Promises instead of observables](#promises)<br> [Promises instead of observables](#promises)<br>
[JSONP](#jsonp)<br> [JSONP](#jsonp)<br>
[Debounce search term input](#more-observables)<br> [Debounce search term input](#more-observables)<br>
@ -272,16 +273,35 @@ code-example(format="." language="javascript").
{ "name": "Windstorm" } { "name": "Windstorm" }
:marked :marked
The server will generate the `id` and return the entire `JSON` representation The server will generate the `id` and return the entire `JSON` representation
of the new hero including its generated id for our convenience. of the new hero including its generated id for our convenience, tucked inside an object
with a `data` property.
Now that we know how the API works, we implement `addHero`like this: Now that we know how the API works, we implement `addHero`like this:
+makeExample('server-communication/ts/app/toh/hero.service.ts', 'import-request-options', 'app/toh/hero.service.ts (additional imports)')(format=".")
+makeExample('server-communication/ts/app/toh/hero.service.ts', 'addhero', 'app/toh/hero.service.ts (addHero)')(format=".") +makeExample('server-communication/ts/app/toh/hero.service.ts', 'addhero', 'app/toh/hero.service.ts (addHero)')(format=".")
:marked :marked
Notice that the second *body* parameter of the `post` method requires a JSON ***string*** The second *body* parameter of the `post` method requires a JSON ***string***
so we have to `JSON.stringify` the hero content first. so we have to `JSON.stringify` the hero content first.
.l-sub-section .l-sub-section
:marked :marked
We may be able to skip stringify in the near future. We may be able to skip the body stringify in the near future.
<a id="headers"></a>
:marked
### Headers
The server requires a `Content-Type` header for the body of the POST.
[Headers](../api/http/Headers-class.html) are one of the [RequestOptions](../api/http/RequestOptions-class.html).
Compose the options object and pass it in as the *third* parameter of the `post` method.
+makeExample('server-communication/ts/app/toh/hero.service.ts', 'headers', 'app/toh/hero.service.ts (headers)')(format=".")
:marked
### JSON results
As with `get`, we extract the data from the response with `json()` and unwrap the hero via the `data` property.
.l-sub-section
:marked
*Reminder*: we must know the shape of the data returned by the server.
The sample web api returns the new hero wrapped in an object with a `data` property.
A different api might just return the hero in which case we'd omit the `data` de-reference.
:marked :marked
Back in the `HeroListComponent`, we see that *its* `addHero` method subscribes to the observable returned by the *service's* `addHero` method. Back in the `HeroListComponent`, we see that *its* `addHero` method subscribes to the observable returned by the *service's* `addHero` method.
When the data arrive it pushes the new hero object into its `heroes` array for presentation to the user. When the data arrive it pushes the new hero object into its `heroes` array for presentation to the user.
@ -313,6 +333,8 @@ code-example(format="." language="javascript").
Our `errorHandler` forwards an error message as a failed promise instead of a failed Observable. Our `errorHandler` forwards an error message as a failed promise instead of a failed Observable.
The diagnostic *log to console* is just one more `then` in the promise chain.
We have to adjust the calling component to expect a `Promise` instead of an `Observable`. We have to adjust the calling component to expect a `Promise` instead of an `Observable`.
+makeTabs( +makeTabs(