2016-05-15 27 views
28

Mi sono imbattuto in un problema strano in cui il servizio Http di Angular2 (RC1) esegue la chiamata http.post due volte. Ho eseguito il debug della mia app e so per certo che questo non è un problema relativo all'evento click. Tutte le chiamate che portano al servizio principale chiamanoAngular2 http.post viene eseguito due volte

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)); 
} 

vengono eseguite una volta. Poi, quando ho iniziato a rintracciare il problema, ho scoperto che il mio gestore this.handleObjectResponse viene eseguito due volte. Così Ho approfondito ulteriormente e ha raggiunto @angular/http/src/backends/xhr_backend.ts dove fanno questo

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 
     ... 
     .. 

così ho messo un punto di interruzione this.request = req; e poi un altro punto di interruzione let _xhr: XMLHttpRequest = browserXHR.build(); e ho scoperto che mi ha colpito il primo punto di interruzione una volta, ma poi mi ha colpito il secondo punto di interruzione dal richiamata due volte.

Questo mi ha fatto impazzire quindi volevo verificare se qualcuno che ha familiarità con gli interni di angular2 potrebbe far luce se questo sembra un bug o qualcosa che ho fatto di sbagliato.

Nel mio codice sono state create alcune classi di servizi generici astratti: GenericService e FullService che estende GenericService. Entrambi sono astratti e usano i generici e le classi di servizio reali che vengono iniettate nei diversi componenti estendono sia GenericService che FullService. Ragazzi, pensate che questa installazione possa essere responsabile delle doppie esecuzioni?

Tutte le idee sono apprezzate!

Grazie in anticipo!

P.S.

Questo non succede con ottiene ma succede anche con puts.

+0

Puoi condividere il codice chiamante? forse c'è un subscribe multiplo sull'osservabile, in questo caso 'return this._http.post (this.createURL (this.getCreateURL(), [], params), body, options) .map (res => this.handleObjectResponse (res)). share(); ' dovrebbe risolverlo https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/operators/share.md – teleaziz

+1

Santo schifo! Grazie mille - questo ha davvero risolto il problema. Ora ho solo bisogno di avvolgere la mia mente su quello che ho fatto per causare questo in primo luogo. Sentiti libero di postare questa risposta come risposta, così posso accettarla e grazie ancora una tantum !!!! – RVP

risposta

53

Il servizio http restituisce un osservabile a freddo che ottiene executed on every subscribe, si desidera convertirlo in un osservabile caldo che viene eseguito solo al primo subscribe e che condivide lo stesso valore per gli iscritti successivi.

Per convertire tutto quello che dovete fare è share esso:

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

Questo commento mi ha aiutato a risolvere un altro problema nell'ultimo RC di Angular2. Grazie uomo. Gli osservabili sono un concetto bellissimo, ma un po 'difficile da capire. –

+3

Quindi dovrebbero essere sostituiti con codice non complicato perché "ingannevole" sta andando indietro, peggiorando le cose, contro perfettamente funzionante –

+3

quindi suppongo SEMPRE di mettere share() dopo una chiamata http è una buona pratica se si restituisce dal metodo –

0

Questo stava accadendo a me perché ho (key.enter)="someSubmitFunction()" su uno dei campi di input di un modulo. Quando premo invio in questo campo, il modulo verrà inviato due volte. Apparentemente, questo non era necessario. Quando ho rimosso questo, il modulo sarebbe ancora inviato quando premo invio, ma ora solo una volta.

0
its happening because HTTP OPTIONS executed first, and you have to restrict unwanted HTTP method before executing your Logic, always use isset method,see example below 

if(isset($_POST)) 
{ 
    $name = $_POST["name"]; 
    $country = $_POST["country"]; 

    $sql = 'INSERT INTO user values("' . $name . '","' . $country . '")'; 

      if ($conn->query($sql)=== TRUE) 
      { 
       $outp = "Inserted " . $name . " and " . $country; 
       echo json_encode($outp); 
      } else { 
       echo json_encode("Error: " . $sql . "<br>" . $conn->error); 
      } 
     } 


here it will insert row in table only when its POST METHOD. 
Problemi correlati