2
votes

I recently started digging around Observables. Currently confused and curious about some concepts. Lets say, I have a simple function whose job is to return the length of the data received from http.get(...).

So, I use Observable to fetch results from web api using angular http service.

My function would look like below -

dataLen:number = 0;
obsData: Observable<any>;

getDataLength(): number {

        this.obsData = return this._http.get(this.baseUrl + 'someMethod').map(res => res.json());
        this.obsData.subscribe(
            data => {
                this.dataLen = data.length;     //suppose data.Length = 5
            },
            err => console.log(err),
            () => { console.log('Length captured successfully'); }
        );                                                                      

        return this.dataLen;        //will this line be executed first before 'this.obsData.subscribe(...);' or 'return' will always be executed last?
    }

Given the aynchronous execution nature of observables, we cannot decide an action to be executed once they are completed. Especially in scenario like above where my function's 'return' code lies after the observable subscribe() block. Here, I need to understand, if return would wait until observable gets completed or it will return the value in hand immediately without waiting for observable to complete? Problem could arise when I am assigning this returned value to some other variable. So I know that once observable completes, it will update the this.dataLen value. But what about the moment I am assigning this.dataLen to some other variable? Do help me understand, at the last, what would be value of this.dataLen? Is it 0 or 5 just after the return statement executes?

1

1 Answers

1
votes

That return doesn't make sense, because your function supposed to be asynchronous while you try to treat it as synchronous. It will return 0 because Js wont wait for subscribe() to complete. Here is a snippet to see whats really happening:

var ob = Rx.Observable.of(1, 2, 3, 4, 5);
var item = 0;

(function() {
  ob.subscribe(num => {
    setTimeout(() => {
      item = num;
      console.log(item + ' in subscribe')
    }, 0)
  })
  console.log(item)  
  return item;
})()
console.log(item)  
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.5.6/Rx.js"></script>

setTimeout is just to mimic HTTP request.