1

In my service, I have defined some method which will use Http.

For example:

getUsers(){
    this._http.get('someapi')
        .map(res=>res.json())
        .subscribe(success=>this.users = success; console.log(success))
}

What I am planing to do, is to set up this method so that it returns a promise, for example:

this.getUsers().subscribe(success=> DO SOMETHING);

or

this.getUsers().then(DO SOMETHING);

So far I got this:

getUsers(){
    var getUsersStream = this._http.get('someapi')
        .map(res=>res.json())
        .subscribe(success=>this.users = success ;console.log('DONE'))

return Observable.of(getUsersStream)
}

Which indeed allows me to do:

this.getUsers().subscribe(success=> console.log('after success'))

however, when I debug, I can see that console output is:

after success
DONE

Which doesnt really works like it supposed to. Where am I doing mistake?

UPDATE

Even though I the answer provided by Thierry works, I guess I will explain my question in bit more detail.

I have method getUserById() in my service, which does the following:

getUserById(someId){
    if(this.users.length){
        var i = _.findIndex(this.users, {"id":someId};
        return this.users[i]
} else {
        this.getUsers().then(find the user)//then should be invoked when users are there
}
}

1 Answer 1

1

You should use this:

getUsers(){
  return this._http.get('someapi')
    .map(res=>res.json())
    .do(success=>console.log('DONE'));
}

The problem is that Observable.of is faster than the HTTP request and you return the first subscription within Observable.of...

If you want an observable waits for a previous observable to execute it, you need to leverage the flatMap operator. Here is a sample:

getUsers(){
  return this._http.get('someapi')
    .map(res=>res.json())
    .do(success=>console.log('DONE'))
    .flatMap(success => {
      // return the new observable. For example a second request
      return this._http.get('someotherapi').map(res => res.json())
    });
}

Edit

Regarding your getUserById method of your service, I would try something like that:

getUserById(someId){
  if(this.users.length){
    var i = _.findIndex(this.users, {"id":someId};
    return Observable.of(this.users[i]);
  } else {
    return this.getUsers().do(users => {
      this.users = users;
    }).map(users => {
      var i = _.findIndex(users, {"id":someId};
      return users[i];
    });
  }
}
Sign up to request clarification or add additional context in comments.

4 Comments

Hmm. So what is the difference between subscribe and do?
It allows to execute some processing without subscribing. See this doc: github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/….
In your case, you don't really want to subscribe within the getUsers method. I guess that you only want at the end ;-)
I've updated my question to be more detailed what is missing - could you take a look. Nevertheless, I really like your answer, and it has helped me in other issue. Thank you!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.