So, you want to do polling to a server using NgRx? I assume you want to wait for each server response before sending new request, and also you want your code to be readable and preferably testable? Perhaps you want to implement long polling? Here is the solution.
disclaimer
Let me begin with a confession - I’m new to state management stuff. I’ve been using NgRx for about 2 months now, so everything below should be taken with a grain of salt.
problem
For the sake of this example, let’s assume that our application is displaying a list of devices that are in our subnet. At any given time, somebody could add or remove a device. Since we have no clue if something like this happened, we have to ask a server for the current state every x seconds.
Our request is a GET to this address: http://localhost:5000/api/subnet.
Response from the server may look something like this:
Let’s assume that time our server needs to scan subnet is 1 - 3 seconds, and a cache is stored for 5 seconds. It means that there is no point in sending a request more often than at least 6 seconds.
The naive approach would be to send a request every 8 seconds (caching time + maximum scanning subnet time). The problem occurs, when something bad happens to our server - browser will keep on sending new requests, even though the server is not responding.
solution
What if instead of setting interval between two requests, we set it between response and request?
In other words, let’s send a request, wait for a response and after it arrives wait for 5 seconds, send another request and so on. Below there is a diagram that shows, what we want to do.
Let’s try to implement that. We will start with something easy, and write our model and actions:
subnetEntry.model.ts
subnet.actions.ts
Next thing we will do is write our reducer. It’s super easy as well.
subnet.reducer.ts
Pretty standard reducer, huh?
Now let’s get to the meat of the problem.
subnet.effect.ts
small effects
I find this way of composing a feature from multiple small effects very useful. If you don’t want to keep any private variable in an effect (isPollingActive), it could easily be stored in the state, and accessed via withLatestFrom operator.