Created
October 10, 2017 06:40
-
-
Save ivanbatic/bb1495d74922dc0110c074f879e9baa7 to your computer and use it in GitHub Desktop.
Rx github fetch demo
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const btnEl = document.getElementById("fetchButton"); | |
const userList = document.getElementById("show_list"); | |
const seriesInput = document.getElementById("series"); | |
// Here we can push new rate limit reset times | |
const rateLimitReset = new Rx.ReplaySubject(1); | |
// Countdowns derived from reset times | |
const resetTicker = rateLimitReset | |
.map(time => Math.ceil(time - Date.now() / 1000)) | |
.switchMap(seconds => { | |
return Rx.Observable.interval(1000).map(i => seconds - i - 1).take(seconds); | |
}).share(); | |
// Retries after ticking came down to 0 | |
const forceRetries = resetTicker.filter(v => v === 0).map(() => seriesInput.value); | |
// [1] Fetch GitHub users that match entered query | |
const userInput = Rx.Observable.fromEvent(seriesInput, "keyup") | |
.debounceTime(300) | |
.map(ev => ev.target.value) | |
.filter(txt => txt.length >= 3) | |
.distinctUntilChanged(); | |
// [1] Make a request to github | |
const githubRequest = query => { | |
const fetched = fetch("https://api.github.com/search/users?q=" + query); | |
return Rx.Observable.fromPromise(fetched).switchMap(response => { | |
const json = Rx.Observable.fromPromise(response.json()); | |
if (response.status === 200) { | |
return json; | |
} | |
return json.switchMap(r => Rx.Observable.throw(response)); | |
}); | |
}; | |
// [1] Take just userInput | |
const fetches = Rx.Observable.merge(userInput, forceRetries) | |
.switchMap(input => githubRequest(input).catch(err => { | |
// [2] take rate limits | |
const remaining = Number(err.headers.get("X-RateLimit-Remaining")); | |
const reset = Number(err.headers.get("X-RateLimit-Reset")); | |
// [2] if we hit the rate limit, push the new reset time | |
if (remaining === 0) { | |
rateLimitReset.next(reset); | |
return Rx.Observable.empty(); | |
} | |
return Rx.Observable.throw(err); | |
})); | |
fetches | |
.map(response => response.items) | |
.map(items => { | |
return items.reduce((acc, item) => acc + `<li>${item.login}</li>`, "") | |
}) | |
.subscribe(output => { | |
userList.innerHTML = output; | |
}, (err) => { | |
console.log("Error!!", err); | |
}); | |
resetTicker.filter(v => v > 0).subscribe(v => { | |
userList.innerHTML = "Cannot fetch data. Retrying in " + v + " seconds."; | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment