I want to set interval in http request using rxjs. I need to send data on server from n seconds after request finish.
Observable.interval(10000)
.?(() => {
//request for server. return Observable
return this.getData();
})
.subscribe(() => {
console.log("Request done. After 10 second will be next request");
});
UPDATE based on .expand()
suggested by Mark
ngOnInit() {
this.getData()
.expand(() => Rx.Observable.timer(10 * 1000)
.concatMap(() => this.getData())
)
.subscribe(data => {
console.log('received new data', data);
});
}
private getData() {
return Observable.timer(5000)
.do(() => console.log("timer"));
}
i think you want to request server for something every few seconds. can you try this way
make sure you have imported import {Observable} from 'rxjs/Rx' if you don't import it we get observable not found error sometimes
working plnkr http://plnkr.co/edit/vMvnQW?p=preview
import {Component} from '@angular/core';
import {Http} from '@angular/http';
import 'rxjs/Rx';
import {Observable} from 'rxjs/Rx';
@Component({
selector: 'app',
template: `
<b>Angular 2 HTTP request every 5 sec RxJs Observables!</b>
<ul>
<li *ngFor="let doctor of doctors">{{doctor.name}}</li>
</ul>
`
})
export class MyApp {
private doctors = [];
constructor(http: Http) {
Observable.interval(5000)
.switchMap(() => http.get('http://jsonplaceholder.typicode.com/users/')).map((data) => data.json())
.subscribe((data) => {
this.doctors=data;
console.log(data);// see console you get output every 5 sec
});
}
}
see google inspect console you will be getting new data every 5 sec
Your usecase is an excellent case for the .expand
operator which can recursively execute and return new values. See this snippet in which i have added a lot of timestamp + debug logging to clarify what is going on.
function getData() { // simulate remote call which can take some time return Rx.Observable.of('') .timestamp() .do(i => console.log(`[debug] Going to fetch data from server @${i.timestamp}`)) .map(i => 'the new JSON blob of data to use') // this would be your actual http.get call .delay(1500) .timestamp() .do(i => console.log(`[debug] Data retreived from server @${i.timestamp}`)); } getData() .expand(_ => Rx.Observable.of('') // we need something to delay upon .timestamp() .do(i => console.log(`[debug] Waiting 1sec for next getData ${i.timestamp}`)) .delay(1000) .concatMap(() => getData()) ) .take(5) .subscribe(val => console.log(`New data received @${val.timestamp} : ${val.value}`))
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.0.3/Rx.js"></script>
so initially you subscribe to the getData()
and expand its value to recursively delay
for time before retrieving the next getData()
. No subjects are involved in this approach and your subscription stays available for receiving the new values.
I've read the comments you put in that deleted answer. You want to send a request, then 10 seconds after receiving a response send another request.
That's quite complex, but doable... I think something like this should work:
let responseSubject = new Rx.BehaviourSubject({});
responseSubject
.delay(10000)
.flatMap(() => {
return http.get(...)
})
.subscribe((res) => {
responseSubject.onNext({});
// Your stuff here
});
Here I'm setting up a behaviour so I can feedback when we get a response. Then setup a stream that after 10 seconds of a request, it makes the request and yields the response.
Edit: I'm missing something... the first request will take 10 seconds before it starts. Then I would rewrite as:
let responseSubject = new Rx.ReplaySubject(1);
responseSubject
.delay(10000)
.startWith({})
.flatMap(() => {
return http.get(...)
})
.subscribe((res) => {
responseSubject.onNext({});
// Your stuff here
});
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.