Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular2 http.post gets executed twice

Tags:

http

post

angular

I came across a weird issue where the Angular2's (RC1) Http service executes the http.post call twice. I've debugged my app and I know for a fact this is not a click event issue. All the calls that lead up to the core service call

public create(json: Object, params?: Object): Observable<T> {
    let body = JSON.stringify([json]);
    let headers = this.getHeaders();
    let options = new RequestOptions({ headers: headers });

    return this._http.post(this.createURL(this.getCreateURL(), [], params), body, options)
    .map(res => this.handleObjectResponse(res));
}

are run once. Then when I started tracing the issue I found out that my handler this.handleObjectResponse gets executed twice. So I delved further and reached @angular/http/src/backends/xhr_backend.ts where they do this

constructor(req: Request, browserXHR: BrowserXhr, baseResponseOptions?: ResponseOptions) {
    this.request = req;
    this.response = new Observable<Response>((responseObserver: Observer<Response>) => {
        let _xhr: XMLHttpRequest = browserXHR.build();
        _xhr.open(RequestMethod[req.method].toUpperCase(), req.url);
        // load event handler
        ...
        ..

So I put a breakpoint on this.request = req; and then another breakpoint on let _xhr: XMLHttpRequest = browserXHR.build(); and I found out I hit the first breakpoint once but then I hit the second breakpoint from the callback twice.

This has been driving me nuts so I wanted to check whether anyone familiar with the angular2 internals could shed some light whether this looks like a bug or something that I've done wrong.

In my code I've created some abstract generic service classes: GenericService and FullService which extends GenericService. Both of these are abstract and use generics and the real service classes that get injected in the different components all extend either GenericService or FullService. Do you guys think this setup could possibly be responsible for the double post executions?

All ideas are appreciated!

Thanks in advance!

P.S.

This doesn't happen with gets but it also happens with puts.

like image 598
RVP Avatar asked May 15 '16 17:05

RVP


2 Answers

The http service returns a cold observable that get executed on every subscribe, you want to convert it to a hot observable that get only executed on the first subscribe and share the same value for subsequent subscribes.

To convert it all you have to do is share it:

return this._http.post(this.createURL(this.getCreateURL(), [], params), body, options)
.map(res => this.handleObjectResponse(res))
.share();
like image 170
teleaziz Avatar answered Nov 08 '22 18:11

teleaziz


This was happening to me because I have (key.enter)="someSubmitFunction()" on one of the input fields of a form. When I hit enter on this field the form would submit twice. Apparently, this wasn't needed. When I removed this, the form would still submit when I hit enter, but now only once.

like image 2
mad_fox Avatar answered Nov 08 '22 18:11

mad_fox