2016-02-11 3 views
12

У меня есть http наблюдаемый, как это так, в моем UserService:angular2 - Navigate после наблюдаемым завершения

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

Я создал наблюдаемое, и создал подписку (response), которая возвращается значение успеха.

Теперь в моем компоненте, я хочу назвать UserService.logout() и затем перейдите к новому маршруту:

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

Очевидно, что это может произойти асинхронно, и я могу закончить навигации, прежде чем я выйти из системы.

Используя обещания, я мог бы сделать что-то вроде этого:

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

Как я могу сделать то же самое с наблюдаемыми? В моем классе UserService я хочу создать наблюдаемый, подписаться на него, сделать некоторые вещи с успехом или с ошибкой, ТОГДА перейти от моего компонента представления.

ответ

14

Вы действительно можете сделать метод logout, чтобы вернуть обещание и использовать его как обычно. Он не должен быть Observable:

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

Очень полезным примером. Спасибо :-) – brinch

0

Вы не можете ждать Observable закончить, потому что его поток может продолжаться до бесконечности. Но вы могли бы назвать router.navigate внутри метода 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']); 
    }); 
    } 

Если этого не достаточно, subscribe возвращает метод Subscription которого unsubscribe останавливается в ожидании данных, которые Observable «s. Поэтому, если вам нужно, вы можете подождать период ожидания и позвонить unsubscribe.

5

Наблюдаемый объект имеет метод, наконец, попробуйте. Не забудьте импортировать первый:

import 'rxjs/operators/finally'; 

Ваш выход из системы() будет:

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

    }); 
    } 

Если вы действительно хотите использовать обещание:

import 'rxjs/add/operator/toPromise'; 

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

в component.ts

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

вы экономите мой день человек !!! это заняло мои 5 часов и, наконец, решило мне проблему – gsiradze

+0

потрясающе! Просто возвращающ благосклонность к общине. Рад помочь. – codely

+2

'finally()' отлично работает, но вы должны его правильно импортировать: 'import 'rxjs/add/operator/finally';' – gkri

0

Выход из эксплуатации должен быть eturn a Observable not a Subscription. Например:

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

Для получения более подробной информации о операторов/методов: https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/observable.md

Смежные вопросы