2016-02-11 38 views
12

Ho un http osservabile in questo modo, a mio UserService:angular2 - Naviga dopo osservabile è completa

logout() { 
    return this.http.delete(this.baseUrl + url, { 
      headers: this.headers() 
     }).map((res: IResponse) => { 
      var json = res.json(); 
      json.headers = res.headers; 
      return json; 
     }).subscribe((response) => { 
      //DO SOMETHING, THEN ---- 
      return res; 
     }); 
} 

ho creato un osservabile, e ha creato un abbonamento (response) che è il successo valore restituito.

Ora, nella mia componente, voglio chiamare UserService.logout() e quindi passare ad un nuovo percorso:

logout() { 
    this.userService.logout(); 
    this.router.navigate(['LandingPage']); 
    } 

Ovviamente, questo potrebbe accadere in modo asincrono e può finire per la navigazione prima di logout.

Utilizzando promesse, avrei potuto fare qualcosa di simile:

this.userService.logout().then(() => { this.router.navigate(['LandingPage']); });

Come posso fare la stessa cosa con osservabili? Nella mia classe UserService voglio creare un osservabile, iscriversi ad esso, fare alcune cose in caso di successo o errore, POI navigare dal mio componente di visualizzazione.

risposta

14

Si può effettivamente fare in modo che il metodo logout restituisca una promessa e usarla normalmente. Essa non deve essere osservabile:

logout() { 
    return new Promise((resolve, reject) => { 
     this.http.delete(this.baseUrl + url, { headers: this.headers() }) 
      .map((res: IResponse) => { 
       var json = res.json(); 
       json.headers = res.headers; 
       return json; 
      }) 
      .subscribe(data => { 
       //DO SOMETHING, THEN ---- 
       resolve(data); 
      }, error => reject(error)); 
    }); 
} 

logout() { 
    this.userService.logout().then(response => this.router.navigate(['LandingPage'])) 
} 
+1

esempio molto utile. Grazie :-) – brinch

0

Non si può aspettare un Observable per finire, perché il suo flusso potrebbe continuare all'infinito. Ma si potrebbe chiamare router.navigate all'interno del metodo subscribe:

logout() { 
    return this.http.delete(this.baseUrl + url, { headers: this.headers() }) 
    .map((res: IResponse) => res.json()) 
    .subscribe((response) => { 
     //DO SOMETHING, THEN ---- 
     this.router.navigate(['LandingPage']); 
    }); 
    } 

Se questo non è sufficiente, subscribe restituisce un metodo Subscription cui unsubscribe si ferma in attesa dei dati s' il Observable. Quindi, se è necessario, è possibile attendere un periodo di timeout e chiamare unsubscribe.

5

L'oggetto osservabile ha finalmente il metodo, provalo. Non dimenticare di importare prima:

import 'rxjs/operators/finally'; 

tuo Logout() sarebbe:

logout() { 
    return this.http.delete(this.baseUrl + url, { headers: this.headers() }) 
    .map(res => res.json()) 
    .finally(() => this.router.navigate(['LandingPage'])) 
    .subscribe((response) => { 
     //DO SOMETHING, THEN ---- 

    }); 
    } 

Se davvero si voleva utilizzare promessa:

import 'rxjs/add/operator/toPromise'; 

logout() { 
    return this.http.delete(this.baseUrl + url, { headers: this.headers() }) 
    .map(res => res.json()); 

in component.ts

var aPromise = this.userService.logout().toPromise(); 
aPromise.then(() => { 
    this.router.navigate(['LandingPage']); 
}); 
+0

risparmi il mio giorno amico !!! ci sono volute 5 ore e finalmente risolto il problema – gsiradze

+0

fantastico! Restituendo il favore alla comunità. Felice di essere di aiuto. – codely

+2

'finally()' funziona alla grande, ma devi importarlo correttamente: 'importa 'rxjs/add/operator/finally';' – gkri

0

Logout necessità di r Eturn a Observable not a Subscription. Per esempio:

logout(): Observable<T> { 
 
     return this.http.delete(this.baseUrl + url, { 
 
       headers: this.headers() 
 
      }).map((res: IResponse) => { 
 
       var json = res.json(); 
 
       json.headers = res.headers; 
 
       return json; 
 
      }) 
 
      .catch((err)=>Observable.empty()) // return empty if error 
 
      .share(); // to ensure that no duplicate http calls can occur 
 
    
 
    } 
 

 
    //in component: 
 

 
    this.service.logout() 
 
     .do(()=>this.router.navigate(['LandingPage']);)//do stuff 
 
     .subscribe((res:any)=>{}); 
 

 
    //or with template async pipe: 
 

 
    public result$ = Observable<T>; 
 

 
    result$ = this.service.logout() 
 
     .do(()=>//do stuff); 
 

 
    //in template: 
 
    
 
    {{(result$ | async)?.id}} 
 
    or simply 
 
    {{result$ | async}} 
 

 
    // P.s. do not forget about unsubscribe(), thats why I prefer to use async (since that's the Async pipe's job.)

Per ulteriori informazioni sugli operatori/metodi: https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/observable.md

Problemi correlati