Skip to content Skip to sidebar Skip to footer

Rxjs - Consume API Output And Re-query When Cache Is Empty

I'm trying to implement a version of this intro to RxJS (fiddle here) that instead of picking a random object from a returned API array, it consumes a backthrottled stream of obje

Solution 1:

I'd do it similarly to the article example with combineLatest() although I wonder if there's an easier way than mine.

I'm making request for only 3 items. Working with 3 items is hardcoded so you'll want to modify this. I was thinking about making it universal but that would require using Subject and made it much more complicated so I stayed with this simple example.

Also, I'm using concatMap() to trigger fetching more data. However, just clicking the link triggers just the combineLatest() which emits another item from the array.

See live demo: https://jsfiddle.net/h3bwwjaz/12/

var refreshButton = document.querySelector('#main');
var refreshClickStream = Rx.Observable.fromEvent(refreshButton, 'click')
  .startWith(0)
  .scan(function(acc, val, index) {
    return index;
  });

var usersStream = refreshClickStream
  .filter(function(index) {
    return index % 3 === 0;
  })
  .concatMap(function() {
    var randomOffset = Math.floor(Math.random() * 500);
    var url = 'https://api.github.com/users?since=' + randomOffset + '&per_page=3';
    return Rx.Observable.fromPromise(fetch(url))
      .flatMap(function(response) {
        return Rx.Observable.fromPromise(response.json());
      });
  })
  .combineLatest(refreshClickStream, function(responseArray, index) {
    return responseArray[index % 3];
  })
  .distinct();

usersStream.subscribe(function(user) {
  console.log(user);
});

I use refreshClickStream twice:

  • to emit next item in the array in combineLatest()
  • to check whether this is the end of the array and we need to make another request (that's the filter() operator).

At the end distinct() is required because when you click index % 3 === 0 time triggers in fact two emission. First is the one from downloading the data and the second one is directly in combineLatest() that we want to ignore because we don't want to iterate the same data again. Thanks to distinct() it's ignored and only the new values is passed.

I was trying to figure out a method without using distinct() but I couldn't find any.


Post a Comment for "Rxjs - Consume API Output And Re-query When Cache Is Empty"