Handle relative time with RxJS

Piotr Sobuś
3 min readMay 29, 2020
Photo by Djim Loic on Unsplash

One of my recent tasks was to create a real-time communicator on the back-end side. To be frank, it was a highly demanding task, but I’m certain, that it has sharpened my skills in data structures and it made me learn and like WebSockets. In addition, I had to supervise and coordinate work on the client-side, so me and my colleague could implement and establish connections more quickly and start testing the communicator before going live. Just before the end of our work, we stumbled upon a task to display and update the relative time of recent messages every minute. In other words — someone has sent you a message, so it would be a good idea to assign a “Just now” information to this message. Suppose a minute has passed, so now we need to calculate how much time has elapsed since you received this message and display this time in the correct format (e.g: 1 minute ago)

The first thought that came to my mind was to create a listener that would fire up after every second and would eventually detect a move to the next minute. RxJS is a great solution for such tasks. This library has a wide range of operators from which you can choose suitable operators for your purposes. After digging in the documentation, I picked some operators and built an observable that looks as follows:

Explanation: this observable runs an interval that emits numbers in a sequence based on provided period. I’ve set the period to 1000 ms which is equivalent to 1 second. While the interval emits a value on each second, I create a Date object with current date and time. I use share operator to share the source among multiple subscribers, so only one interval will be up and running. Next, I’ve put a startWith operator to emit the Date object right after someone subscribes to the observable. Lastly, I use pairwise, which is a powerful operator and its purpose is to put the current value and previous value together as an array and emit that, so we can compare the time and check if the minute has turned into the next.

You may think the observable provided in the example consumes a lot of resources and can considerably worsen the performance of your application, but keep in mind, that you can set the period to a higher value which will translate into less memory consumption. On the other hand, there is an alternative solution. You can create two intervals, the first interval will emit only once and it will emit when a new minute kicks in. This can be achieved by setting a dynamic period (calculate how many seconds have to pass to reach to a new minute). After emitting a value, we can refresh the relative time of all text messages and switch to the second interval which will emit a value every 60 seconds. Following this path, we are certain that our listener will be synchronized with our clock. However, you may ask, why we need the first interval, but eventually you’ll notice that someone can refresh the page and land in the middle of the minute count. Here is the implementation:

In this solution, I use skipUntil to ignore emitted values until the first interval has emitted. Moreover, I added a last operator to wait for the first stream to complete and grab the latest value, so this way I can pass the value through and cancel the skipping. You can now subscribe and execute your function to refresh your messages on each emit.

Service as Observable

Let’s put our logic to a service, make little changes and turn this service into Angular-style service using RxJS Observable.

Consume it like presented below:

Conclusion

I strongly advise you to dive deep into the RxJS documentation, you’ll find helpful operators with comprehensible and clear examples. I wish you good luck in building your own basic or complex observable.

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!

--

--