Listen for application state change in RxJS

Piotr Sobuś
3 min readMay 9, 2021

There are a lot of Web APIs available for developers that can be consumed and used for various situations. Page Visibility API is one of them. I have some great experience using this API and would like to share some of what I have learned, what type of problem I used it for and how I integrated it with my favorite framework — which is Angular.

Photo by Luke Chesser on Unsplash

Recently, I have been given a task to extend the functionality of a polling system in our web application to such an extent that it becomes paused on a given condition. The requirements were straight-forward. When the user minimizes the browser, switches to another tab or loses focus on the application, the system should pause and continue its work when user comes back to our application. I stumbled upon the Page Visibility API and implemented it in our application the reactive way using RxJS. Generally, for small applications, you will most likely never use this, unless you have a large inter-connected application that has a polling system that sends requests to the backend server periodically in order to validate user’s session or timers that run different tasks every specified duration, it can be very beneficial in matters of performance. Let me go through the building process of my application status listener and show my solution to the problem, taking into the account the aformentioned requirements.

First, I created a shareable service that inherits from Observable<T>. Since no class methods were needed and we only need to subscribe in order to listen for application state change, creating a Service as Observable was a reasonable approach. The Page Visibility API provides visibilitychange event we can watch for to know when a document becomes visible or hidden, as well as features to look at the current visibility state of the page. Take a look at this code:

Three things to notice here. I used startWith with true, because I assumed, every time the application loads, the user actually sees our website. Secondly, I check against the hidden value instead of visible value, thanks to that I take prerender and unloaded state into consideration as well. Thirdly, I provide document object as a dependency, because our application does not necessarily needs to be run on the browser (we can execute it on server side or run it on a test environment). Using Dependency Injection and tokenizing things encourage good patterns.

However, the solution is not fully satisfactory as we don’t meet the last requirement. Consider a case, where the users focuses out of our application and switches to his second display screen, technically our listener should emit an event as the application goes in inactive state but it won’t, because Page Visibility only addresses to us a signal when the page is not visible to the user anymore. We can solve this by listening on the window object for focus and blur events simultaneously, but before that, let’s tokenize the window object:

Next, inject our dependency into the constructor and merge both of these events:

Let’s combine both of these streams and produce a single source of truth:

Everything works as expected now. I provided a full solution down below.

Conclusion

The Web API offers tons of features we can play with and use them in our daily projects. Moreover, if we want to transform our code to reactive fashion, RxJS comes in handy, so it will surely give you more fun and increase your productivity while coding.

That’s it. Thanks for reading. If you liked the post, please give me an applause. If you have any questions, feel free to ask them in the comments!

--

--