Patrik Laszlo
Patrik Laszlo

Reputation: 5088

ReactiveX Observable to trigger when I want to

I try to trigger an Observable like as a click as well an interval. How can I trigger?

I tried obs.retry(), but it does nothing.

constructor(private http: Http) {
    this.obs = this.http.get('http://quotesondesign.com/wp-json/posts?filter[orderby]=rand&filter[posts_per_page]=1');
    obs.subscribe((response) => {
        console.log(response.text());
    })
    setInterval(() => {
        console.log('update');
        this.obs.retry();
    }, 1000)
}

onClick() {
   console.log('click');
   this.obs.retry();
}

Upvotes: 0

Views: 120

Answers (1)

olivarra1
olivarra1

Reputation: 3399

You have to resubscribe when you want to "retry".

When you construct an observable, like when you do this.http.get(...) you are just defining what you will want to do with data. So you are saying "I want to get the data from the server, then filter out the data I don't want (.filter(...)) and map it to my object definition so I can use it (.map(...))", but not making any of those actions just yet.

When you .subscribe() to that observable, you are running all these operations you just defined. So in this case, you should do something like:

constructor(private http: Http) {
    this.obs = this.http.get('http://quotesondesign.com/wp-json/posts?filter[orderby]=rand&filter[posts_per_page]=1');

    setInterval(() => {
        console.log('update');
        this.loadPosts();
    }, 1000)
}

loadPosts() {
    this.obs.subscribe((response) => {
        console.log(response.text());
    });
}

onClick() {
    console.log('click');
    this.loadPosts();
}

If you understand this part, then you can look into making this a full Rx solution:

constructor(private http: Http) {
    let httpStream = this.http.get('http://quotesondesign.com/wp-json/posts?filter[orderby]=rand&filter[posts_per_page]=1');
    this.clickSubject = new Rx.ReplaySubject(1);

    this.obs = Rx.Observable.interval(1000)
        .merge(this.clickSubject)
        .flatMap(() => httpStream);

    // Note that is not a good practice to have subscribe in constructors, should have this in init() method or something similar.
    this.obs.subscribe(() => {
        console.log(response.text());
    });
}

onClick() {
    console.log('click');
    this.clickSubject.onNext();
}

Here I'm setting up a stream that ticks every second (Rx.Observable.interval), join that stream with one that yields every time there's a click (this.clickSubject) and maping each tick for a new result of the httpStream.

Upvotes: 1

Related Questions