I'm trying to implement a "save on type" feature for a form using RxJS v5 beta.
The data should be posted to the backend as the user types into the text fields. I'm creating a Rx.Subject
to fire new events (next()
) for new user input and post it with HTTP requests.
I've used this question as a starting point: RxJS wait until promise resolved
However, with the solution from this post, simultaneous request to the backend are sent.
My goal is to only send one request and defer following requests until a running request has completed. After completion of the request the last of the pending events should be emitted (like it is the case in debounceTime
)
The example
function in the following snippet uses the approach from the linked SO question. This sends requests for all the input values.
The workaround
function function uses a promise stored outside of the "stream" to block and wait for a previous request. This works and only sends a request for the last input value. But that seems to not follow the concept of RxJs and feels hacky.
Is there a way to achieve this with RxJS?
function fakeRequest(value) {
console.log('start request:', value)
return new Promise((resolve) => {
setTimeout(() => resolve(value), 1000);
});
}
function example() {
let subject = new Rx.Subject();
subject
.debounceTime(500)
.switchMap(input => fakeRequest(input))
.subscribe(data => console.log(data))
subject.next('example value 1');
subject.next('example value 2');
subject.next('example value 3');
subject.next('example value 4');
}
function workaround() {
let subject = new Rx.Subject();
let p = Promise.resolve();
subject
.debounceTime(500)
.switchMap(input => p.then(() => input))
.do(input => p = fakeRequest(input))
.subscribe(data => console.log(data))
subject.next('workaround value 1');
subject.next('workaround value 2');
subject.next('workaround value 3');
subject.next('workaround value 4');
}
example();
// workaround();
<script src="https://unpkg.com/@reactivex/rxjs@5.0.0-rc.2/dist/global/Rx.js"></script>