Kai Chan
Kai Chan

Reputation: 11

AngularJS 2 observables http change detection

Not been doing Angular2 for long, so apologies if I'm not understanding observables correctly ... in a component I'm subscribing to getData which sits in a service class. What I want is for the http get to call and emit changes automatically back to the caller/subscriber when url changes (and maybe any other URL parameters for that matter). How can this be achieved? Am I not understanding observables correctly maybe?

@Injectable()
export class HttpService {

    url: string;

    constructor(
        private http: Http
    ) {}

    getData() {
        return this.http.get(`${this.url}`)
            .map((res:Response) => res.json());
    }

    setUrl(url) {
        this.url = url;
    }
}

Upvotes: 0

Views: 503

Answers (1)

AngularChef
AngularChef

Reputation: 14087

With your implementation, getData() uses whatever value this.url holds at the time getData() is invoked. In other words, if you change this.url AFTER you called getData(), nothing will happen.

To do what you describe, you need to wrap the stream of different URLs inside an observable:

import {Subject} from 'rxjs/Subject';

@Injectable()
export class HttpService {
  // The `url` property is replaced with an observable emitting a stream of URLs.
  private _urlsStream: Subject<string> = new Subject<string>();

  constructor(private http: Http) {}

  // The http.get() now gets its urls from the url stream.
  // Every time a new url is pushed to the stream, a new request is executed.
  getData() {
    return this._urlsStream.asObservable()
      .mergeMap((url: string) => this.http.get(url))
      .map((res: Response) => res.json());
  }

  setUrl(url) {
    // Setting an url pushes the given url to the stream.
    this._urlsStream.next(url);
  }
}

This code is definitely more involved than the original version. I've added comments to clarify but if you're new to RxJS I highly suggest you spend some time reading the manual and watching some tutorials.

You'll want to learn about:

  • The different types of observables (I used a Subject, which is a special type of observable that can both emit values and be subscribed to).
  • The different types of operators (I used mergeMap() to "project" one observable - the stream of URLs - into another observable - the HTTP requests).

Upvotes: 4

Related Questions