8

I have the following code that returns an observable, it checks if the this.data is valid JSON, otherwise it tries to fetch it from url. The fetching and everything works.

load():Observable<IStandardListOutput[]> {

return Observable.create(observer => {

  if (this.needsFetch) {
    var data;
    this.http.get(this.data)
      .map(res => {
        var result = res.text();
        // console.log(result);
        try {
          data = JSON.parse(result)
        } catch (e) {
          return Observable.of([{error:"ERROR LOADING JSON: " + this.data}]);
        }
        return data;
      }).subscribe(res => {
        observer.next(this._parse(res));
        observer.complete();
      });
  }else {
    observer.next(this._parse(this.data));
    observer.complete();
  }
});

}

Now in the map/subscribe portion of the observer I have the following:

let observable$ = this.loader.load(); // <-- load method above
observable$.map(res => {
  console.warn ("IN MAP: " + JSON.stringify(res));
});

observable$.subscribe(res=> {
    console.log("IN SUB: " + JSON.stringify(res));
  },
  err => {
    console.log(JSON.stringify(err))
  },
  () => {
    console.info("COMPLETE")
  }
);

What I see in the output/console is only the "IN SUB" (subscribe) function and a "COMPLETE". The console.warn in the .map function is never executed.

Any help is highly appreciated, thanks in advance

pythic
  • 223
  • 1
  • 2
  • 6
  • Chech in here http://stackoverflow.com/questions/34671715/angular2-http-get-map-subscribe-and-observable-pattern-basic-understan – Amy Nov 01 '16 at 10:17

2 Answers2

15

The map is never executed because it creates an observable that stays cold (no subscription). Add an empty subscribe() and it should work.

observable$.map(res => {
  console.warn ("IN MAP: " + JSON.stringify(res));
}).subscribe();

And another tip on rxjs debugging, if you want to peek into the value, you can always use the do operator (instead of your map).

observable$
  .do((v) => console.log('debug point: ', v)) // <-- this is the addition.
  .subscribe(...your original handlers go here ...)
Meir
  • 14,081
  • 4
  • 39
  • 47
  • How com your answer is different than mine, your map doesn't return anything at all – Fabio Antunes Nov 01 '16 at 10:19
  • It sticked with the original code, just activated it. Yet, since the observable becomes hot, it will go through the map and print. If it was .subscribe(v => console.log(v)) it would present an empty value. Your example assigned observable$ = observable$.map(...) it changes the observable and the following subscription will fail. – Meir Nov 01 '16 at 10:21
  • 1
    okay, thank you now it works. I thought subscribing to the observable$ was enough ... (/me Observable n00b) :( – pythic Nov 01 '16 at 10:22
  • an rxjs noob :-) But if all you wanted was to debug print, the do() is cleaner. And actually, you don't need to .map().subscribe(), directly subscribe to it. But, making mistakes is a great way to learn. – Meir Nov 01 '16 at 10:25
1

rxjs changed a lot. Angular 2 (8) is very different from AngularJS.

Since version 6 from rxjs, you need to import it with

import {map} from 'rxjs/operators';

and, in your code, include it with a pipe, for example:

observable.pipe(map(res => res.json()).subscribe( {
console.log("IN SUB: " + JSON.stringify(res)); },
  err => {
    console.log(JSON.stringify(err))},
  () => {
    console.info("COMPLETE")
  }

hope this helps!

Arthur Zennig
  • 2,058
  • 26
  • 20