Send new requests from refresh clicks in RxJS

André Staltz
InstructorAndré Staltz

Share this video with your friends

Send Tweet
Published 7 years ago
Updated 3 years ago

In this lesson we learn how to fetch new data whenever the refresh button is clicked. This lessons starts to give us a feeling of how is it to develop reactive applications in RxJS.

[00:01] So now, let's try to implement that feature, which is when we click the refresh button, we should get even more users being displayed here. How do we do that?

[00:13] First of all, we know that when clicks happen on this refresh button, those should be represented as an event stream, just like everything else is. We can use from event -- we have seen this before -- from this element, the refresh button and from the type click.

[00:36] Now we have the refresh click stream, but the click events don't carry themselves an API URL. That's what we need in order to do the network request.

[00:50] We need to map each of these clicks to an actual URL. We need to change the request stream to be the refresh click stream to be mapped to something. So we're going to map each of these events to something.

[01:10] Here, we want to return a URL, for instance, of the API users. We should give also a random offset here, because we want to get different users. So we make a random offset. There's a number between 0and 500, and we put that here. OK.

[01:43] Now, requestStream works in a different way. Whenever refresh happens, it will be mapped to a URL. Then the response will pick that up by mapping the request to something, and it should work.

[02:00] But now, if you're clever you notice that this doesn't actually do any request in the beginning, because since we're mapping clicks to URLs, if I don't ever click that, then I will never get a URL in the request stream.

[02:18] This data being displayed here is coming from the HTML. We're not really getting any data at all from the back end here, because I simply haven't clicked here yet. I actually broke the feature that we had before.

[02:32] Why is this happening? Well, we need to have an initial request. We need to have the start up request, and sort of I broke that, so we need to put that back somehow. Let's make a stream that has only that start up request. Just basically what we had there before, but just with a different variable name. Users.

[03:02] Now, this is a lonely requestStream. It's not being used by the responseStream. The responseStream here only uses requestStream. It's not using startupRequestStream. This one is actually requestOnRefreshStream, and we're only doing this one.

[03:26] How can we get that one to be used also for the response? Well, we can do something here called merge startupRequestStream. When we do this, as you can see, we already got data here. This came from the startupRequestStream. Then if I click refresh, we will get even more users.

[03:51] So, what did I just do here with merge? Merge is this kind of operation that gives you back an observable with events from either this or that. If we draw a marble diagram for that, it looks somehow like this. So let's say we have A, B, and C. Let's actually suppose that these are events from the requestOnRefresh.

[04:19] Then we have events from startupRequestStream. It looks like this, because there's only one event, and it happens in the beginning.

[04:31] Then when we merge, it will simply make an output observable that has events from both of those. It means that it has this S event, it also has A, and it also has B, and it also has C. This is what we get as this operation here.

[04:55] It has events from startupRequest, and it also has events from requestOnRefresh. That's how we got this output that we see here.

~ 7 years ago

Why do you need flatMap in the responseStream?

André Staltz
André Staltzinstructor
~ 7 years ago

Hi Joshua, if we try to simply map a request URL to a response, we will get a stream of streams, because each response is a stream (since a response always comes asynchronously in the future). With a stream of streams, we can "flatten" it by using mergeAll. So map + mergeAll is what we would need to do. Actually, flatMap is precisely map + mergeAll. That's why we use flatMap.

JL decentraliser
JL decentraliser
~ 4 years ago

OMG please update to RXJS 6, took so long for me to find how to use merge :'( for those who are like me (I use node-fetch):

var responseStream = merge(startupRequestStream, requestOnRefreshStream). pipe( flatMap(requestUrl => from(fetch(requestUrl).then(res => res.json())) ) );