Reputation: 2945
I use Angular2 2.4.8. I fetch data using Http
service:
fetchData(urls: string[], computer: Computer): Observable<Computer> {
let stream$ = <Subject<Computer>>new Subject();
let requests = new Map<string, Observable<Response>>();
urls.forEach(url => {
requests.set(url, this.http.get(url));
});
Observable.forkJoin(Array.from(requests, x => x[1]))
.subscribe((responses: Response[]) => {
// put data from responses into computer (API gives data in pieces)
stream$.next(computer);
stream$.complete();
},
(e: Response) => {
// do something with error
stream$.error(e.json());
});
return stream$.asObservable();
}
Now I need to refresh data periodically (polling). The difficulty is that the frequency should be different for different urls. Can I achieve this using Rx?
Maybe instead of parameter urls: string[]
I could pass array of objects with url and fefresh frequuency. But I don't know how to solve this in Rx.
Upvotes: 0
Views: 430
Reputation: 96891
This really depends on what exactly you're trying to do and how you want to handle the Observable returned from fetchData()
.
In general, if you want to periodically repeat a request you can use the repeatWhen()
operator and chain it with delay()
:
urls.forEach(url => {
requests.set(url, this.http.get(url)
.repeatWhen(notifier => notifier.delay(XXX)));
});
Also, if you want to repeat the requests you can't use the forkJoin()
because it'll just emit values and complete immediately.
In this case both combineLatest()
or zip()
seems good depending on what you want to achieve.
Upvotes: 0
Reputation: 16846
If you want to periodically make HTTP requests, you need to use .interval
. This will allow you to "trigger" a new request now and then.
For example:
function poll (tuple) {
return Rx.Observable.combineLatest(
tuple.map(({url, time}) => {
return Rx.Observable
.interval(time)
.switchMap(val => Rx.Observable.of(`${url}: ${val}`));
})
);
}
poll([
{ url: 'foo', time: 500 },
{ url: 'bar', time: 100 }
]).subscribe(val => console.log(val));
<script src="https://unpkg.com/rxjs/bundles/Rx.min.js"></script>
Replace the Rx.Observable.of
part with your http
service.
Upvotes: 1