Let's see next how to use the HTTP driver to generate requests and capture responses. We will build a small app to fetch a single piece of data from a REST server and display that on the DOM.
That object contains a function called makeHTTPdriver. We can restart our main from scratch. Then we're going to include the makeHTTPdriver. We'll make [inaudible 0:40] HTTPdriver function. Now we're ready to start, but what are we going to use as our server?
We can use this placeholder API server, and it has just fake data. We're going to use the users endpoint. Now, it has an array with objects for 10 users here as user data. Our goal will be to create a simple app that just fetches data for the first user and displays that on the DOM.
As usual, I recommend that you start by returning object of sinks. Here, as a DOM sink, we're going to have an observable with just one event to display static data on the DOM. We're going to need an H1 header, H4 and A link. Then we can make a DIV with children.
First we're going to make a button with class. Then get first and text content, get first e-user. Then we're going to make a section for the user details with not a button, but a header with username and some placeholder data for the user's name. Right now we don't have any real data, so we need to use this placeholder.
Then we also have a link for the user's website with the h-ref attribute can be some placeholder as well, and then, here, website. This was all static elements on the DOM. Nothing's dynamic yet. Nothing happens when I click the button.
The way this app should work is that when I click on the button, it should immediately make a request for the first user. Then, after route, we receive the response for that request. Then we get that response data and display it on the DOM here.
Let's write those steps that I just said down as a comment here. The button was clicked. Then, after that, we sent a request. We get the response, and then we display the data.
Usually, if you're stuck, if you don't know how to write main, you write down these steps of what the user is doing, and you ask yourself, "Which of these are write effects, and which of these are read effects?"
We know that usually displaying data on the DOM is a write effect, and not just a write effect, but it's a DOM write effect. Similarly, detecting clicks or user events are DOM read effects. We saw that from previous lessons.
What are requests being sent and what are response being received? This is an HTTP write effect, and this one is an HTTP read effect. Now this will guide us to writing our main. We know that write effects are sinks, and we know that read effects are coming from the sources.
All we need to do is create a DOM sink for this one, HTTP source for this one and HTTP sink for that one. We know how to do this.
We can start by making the DOM read effect, which is coming from the sources at DOM. That's a stream of click events coming from the source .DOM. We're going to select the get first button element, and we're interested in the click events.
Then we're supposed to make the request stream. That is going to become our write effect, so it's going to become an HTTP sink, like that.
What is request stream? Every time we click on the button, it should make a request. We're literally mapping click events to instructions for requests. Here, inside this map, we should return an instruction for requests.
In the HTTP driver, it expects an object to describe that request. The object usually has two field, URL and method, but it can also have other fields to customize the request. For the URL, we're going to use this JSON placeholder endpoint for the users, and /1 for the first user, and then the method is get.
Each of these clicks are being mapped to request objects. These request objects are being sent to the HTTP drivers as write effects.
Sending requests to the air is not enough. We need to capture, also, the responses coming. Just making the requests is not enough, we need to receive those responses. Responses are read effects, so that's why we need to get them from sources.HTTP.
Sources.HTTP works in a similar fashion that sources.DOM does. Sources.DOM represents basically everything happening on the DOM that you can read. From that everything, we want to filter for only those click events that we're interested in.
It's the same approach here. We have basically all of the possible responses and readable stuff happening on the HTTP layer. From that, we're going to filter for those things that we are interested in. In particular, we're interested only in requests that have this URL.
What sources.HTTP returns you is actually response stream stream. Now, this dollar sign looks new. It looks different because usually we have just one dollar sign. You read this as dollar sign means this is a stream that emits click events, just as here we have a stream that emits request objects.
Here, we have a stream emits response streams. If I would plot that in a diagram for you, it would look like this. We have the response stream stream, and each of the Rs that it emits, they are also streams.
We're branching off from the originating response stream stream. This whole thing is response stream stream, and each of these items being emitted is a response stream.
What we're going to do in this filter is say, "I only want these branches, these response streams, that are related to this URL here. Since this stream emits response streams, we're going to filter for response streams.
This response stream happens to have, this branch here, happens to have a field called request, which points to the originating request object. It's basically the same object here. That request object has a URL field, which allows us to check if it's the same URL as we gave here, like that.
What we're doing here is we're saying we only want these branches that were originated from this request. It might remove some of these here. Maybe that one was related to requests for some kind of Google server. We only want requests that are related to this JSON placeholder.
Now we still have this response stream stream. What we need next is response stream, simply. We do that by simply flattening this response stream stream. There are a couple of operators that do flatten. This is not really an operator. There are multiple of them. There are switch, and there's merge all.
We can just use switch in this case. We do switch, then it converts response stream stream to response stream. That looks like this, basically. It looks flat and nice like a normal observable.
From that, you can see that this is a stream that returns response objects. We need to get the first user data by mapping each of these response objects to the body of the response data.
Now that we have this first user stream as the stream of user data from the server, we can simply map these to the DIVs that will contain the user data. This is the name, and this one is the first user email. Here we have the website, like that.
Nothing is happening here, on the DOM. That's because we are mapping this to that. Initially, nothing really happens here because, in order to have a response, we need to have requests. In order to have requests, we need to click. If we don't click on that button, which doesn't exist yet, we are never going to get this. Initially this is emptiness, and if we map emptiness to something, we're going to get emptiness. That's why we see emptiness here.
As usual, we need to use that trick of prepending. Start with a null user data. We're saying that initially we have no user data. We're going to have null being emitted first. That's what we have here. Then we can check if the first user is null, we're not going to render that DIV, we're just going to render null. If this first user data is not null, then we're going to render this DIV.
If I try clicking this button, still nothing happens. We can debug with console log what is happening here.
When I click the button it says, "The page was loaded over HTTPS, but we requested..." Yeah. This is not a cycle.js problem. It's a js.bin problem. We're requesting for HTTP, but js.bin hosts on HTTPS.
We need to actually run this whole example from a page which is served under HTTP. This is just HTTP. You always have core issues or protocol issues. What we're going to do is view this page under HTTP.
I get this page. We're going to view it. We're going to click the button. After a while, we get our user data.
That's basically how you use the HTTP driver to make these read and write effects HTTP layer.