0

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;
    }
}

1 Answer 1

4

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).
Sign up to request clarification or add additional context in comments.

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.