180

When I make a post request the angular 2 http is not sending this request

this.http.post(this.adminUsersControllerRoute, JSON.stringify(user), this.getRequestOptions())

the http post is not sent to the server but if I make the request like this

this.http.post(this.adminUsersControllerRoute, JSON.stringify(user), this.getRequestOptions()).subscribe(r=>{});

Is this intended and if it is can someone explain me why ? Or it is a bug ?

Nicu
  • 3,476
  • 4
  • 23
  • 43

3 Answers3

292

Since the post method of the Http class returns an observable you need to subscribe it to execute its initialization processing. Observables are lazy.

You should have a look at this video for more details:

Thierry Templier
  • 198,364
  • 44
  • 396
  • 360
81

You must subscribe to the returned observable if you want the call to execute.

See also the following angular documentation "Communicating with backend services using HTTP".

Starting the request

For all HttpClient methods, the method doesn't begin its HTTP request until you call subscribe() on the observable the method returns.

This is true for all HttpClient methods.

You should always unsubscribe from an observable when a component is destroyed.

All observables returned from HttpClient methods are cold by design. Execution of the HTTP request is deferred, letting you extend the observable with additional operations such as tap and catchError before anything actually happens.

Calling subscribe() triggers execution of the observable and causes HttpClient to compose and send the HTTP request to the server.

Think of these observables as blueprints for actual HTTP requests.

In fact, each subscribe() initiates a separate, independent execution of the observable. Subscribing twice results in two HTTP requests.

const req = http.get<Heroes>('/api/heroes');
// 0 requests made - .subscribe() not called.
req.subscribe();
// 1 request made.
req.subscribe();
// 2 requests made.

On a related note: The AsyncPipe subscribes (and unsubscribes) for you automatically.

Igor
  • 60,821
  • 10
  • 100
  • 175
47

Get method doesn't require to use the subscribe method but post method requires the subscribe. Get and post sample codes are below.

import { Component, OnInit } from '@angular/core'
import { Http, RequestOptions, Headers } from '@angular/http'
import 'rxjs/add/operator/map'
import 'rxjs/add/operator/catch'
import { Post } from './model/post'
import { Observable } from "rxjs/Observable";

@Component({
    templateUrl: './test.html',
    selector: 'test'
})
export class NgFor implements OnInit {

    posts: Observable<Post[]>
    model: Post = new Post()

    /**
     *
     */
    constructor(private http: Http) {

    }

    ngOnInit(){
        this.list()
    }

    private list(){
        this.posts = this.http.get("http://localhost:3000/posts").map((val, i) => <Post[]>val.json())
    }

    public addNewRecord(){
        let bodyString = JSON.stringify(this.model); // Stringify payload
        let headers      = new Headers({ 'Content-Type': 'application/json' }); // ... Set content type to JSON
        let options       = new RequestOptions({ headers: headers }); // Create a request option

        this.http.post("http://localhost:3000/posts", this.model, options) // ...using post request
                         .map(res => res.json()) // ...and calling .json() on the response to return data
                         .catch((error:any) => Observable.throw(error.json().error || 'Server error')) //...errors if
                         .subscribe();
    }
}
muratoner
  • 2,316
  • 3
  • 20
  • 32