70

I am trying to take advantage of observables in angular2 and got confused on why should i use map() over subscribe(). Suppose i am getting values from a webApi, like this

  this.http.get('http://172.17.40.41:8089/api/Master/GetAllCountry')

Now using subscribe(success, error, complete) I can get all the values on the success callback and I can return the values on the complete callback. If I can do all theses functionalities then what is the need of map()? Does it give any advantage?

In short, why one should write like this:

this.http.get('http://172.17.40.41:8089/api/Master/GetAllCountry')
    .map(r=>{})
    .subscribe(value => {
    }, error => error, () => {
});

when they can simply write this without the map function:

this.http.get('http://172.17.40.41:8089/api/Master/GetAllCountry')
    .subscribe(value => {        
    }, error => error, () => {           
});
2
  • i have updated my question, please have a look at it Commented Feb 20, 2017 at 11:06
  • 3
    .map(r=>{}) will result in undefined value. Please, explain your case in a reasonable way if you're looking for a reasonable answer. Commented Feb 20, 2017 at 11:06

6 Answers 6

94

If you want to return an Observable some other code can subscribe to, but you still want to manipulate the data events in the current method, use map.

The actual user of the observable needs to subscribe(), because without subscribe() the observable won't be executed at all. (forEach() or toArray() and probably others work as well to execute the observable instead of subscribe())

subscribe() returns a Subscription that can not be subscribed to, but it can be used to cancel the subscription.

map() returns an Observable which can be subscribed to.

Sign up to request clarification or add additional context in comments.

1 Comment

To add to the answer, operations in map are executed asynchronously whereas operations in subscribe are executed synchronously. There's a performance improvement, albeit probably not huge in most cases, to doing as much work as possible in the map call.
35

Think map as a middleware which transforms the response.

this.http.get('http://172.17.40.41:8089/api/Master/GetAllCountry')
.map(r=>r.json())
 .subscribe(result => {
              // here result would have json object that was parsed by map handler...
            },failurCallback,completeCallback)

subscribe is used to invoke the observable, please read a good doc on cold-vs-hot-observables

Comments

18

You need subscribe to run your async request. If you just set map - no requests will trigger. You can check.

Good practice to use map to preproccess you data because many subscribers can comsume your results. So instead of adding preprocessing to each client (subscriber) you can prepare single output with single data schema for all.

1 Comment

The first paragraph doesn't answer the question, as OP isn't asking whether to subscribe or not. The second paragraph, however, is great. For some reason, the way you put it made more sense than the accepted answer for me. Thanks!
3

Observables are streams and they are designed to be written in functional streams. You should use RxJS operations because it is the 'functional' way of implementing subsctiptions to observables. Usually this happens when we take data outside of the Observable stream.

This is an asynchronous operation forced to work synchronously.

bad_example() {
  let id;
  this.obs.subscribe(param => id = param['id']);
    this.get(id).subscribe(elem => this.elem = elem);
}

This is an asynchronous operation that works as supposed to work. (As a stream)

good_example() {
  this.obs
    .map(param => param['id'])
    .switchMap(id => return this.get(id))
    .subscribe(elem => this.elem = elem);
}

2 Comments

so in the bad example you have used a variable to store data, and in your good example as you claim, you have this private member! please distinguish your opinions from good & bad practices
This is an asynchronous operation forced to work synchronously , so I think it is a bad practice to do that
2

.map() is an rxjs operator, it will show the result in array [] form either .json() form

https://www.learnrxjs.io/operators/transformation/map.html

Comments

0

When you need to manipulate an Observable array you would need to use something like RxJS map which will give you access to the array object as an array you can manipulate. In other words, you can't directly change/update an Observable array. You have to use RxJS to transform data like this:

filterTodos() {
    // filter to show favorites only
    this.todosList = this.todosList.pipe(
      map((currentTodos: Todo[]) => {
        return currentTodos.filter((currentTodo) =>
          currentTodo.completed === true);
      })
      )
  }

the RxJS map function transforms the todosList Observable array into one that can be manipulated. You have to use RxJS functions instead of array manipulation functions.

Use subscribe to listen to changes to an Observable. Use map, filter, etc to manipulate the Observable array. The RxJS map, filter is

Comments

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.