Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

angular2 - Navigate after observable is complete

I have an http observable like so, in my UserService:

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

I have created an observable, and created a subscription (response) which is the returned success value.

Now, in my component, I want to call UserService.logout() and THEN navigate to a new route:

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

Obviously, this could happen asynchronously and I may end up navigating before I logout.

Using promises, I could do something like this:

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

How can I do the same thing with observables? In my UserService class I want to create an observable, subscribe to it, do some stuff on success or on error, THEN navigate from my view component.

like image 591
JMac Avatar asked Feb 11 '16 22:02

JMac


2 Answers

You can actually make logout method return a promise and use it as normal. It doesn't have to be 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']))
}
like image 60
dfsq Avatar answered Nov 05 '22 10:11

dfsq


Observable object has method finally, try it. Don't forget to import first:

import 'rxjs/operators/finally';

Your logout() would be:

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

    });
  }

If you really wanted to use promise:

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']);
});
like image 42
codely Avatar answered Nov 05 '22 09:11

codely