Pattern Intoduction to Rxjs

Recently, we upgraded our mobile app from Ionic 1 to Ionic 5. 

Wrapping our head around Angular, after working for so long in angular js, wasn't too big of a hurdle.

The problem with Rxjs - it's difficult to find examples of how to do stuff.

Take for example, infinite scroll.

What is infinite scroll?

When the user opens the page showing the rows of data - you will load up the first 10 rows.

When the user has scrolled near the end of the page, you can check if a new page is there and if yes, make an api call to fetch the next page and append it to the end of the pre existing list.

And not just vanilla infinite scroll, it was chocolate cake infinite scroll with cherry on top- 

  • Infinite scroll to be present as default
  • Filters and sorting can be applied from the UI
  • When search is used, all of the data is to be pulled in (so that we can filter everything by text)
  • On pull to refresh, invalidate the cache and reload data

We had our work cut out for us and doing it the right way was very necessary since this is used in very critical pages.

With Rxjs - things started to feel easier once we got around learning how to think about them. 

This blog won't contain any tutorials for Rxjs but make you familiar with two design patterns which will help you understand what is going on when you start working with rxjs.

What are design patterns?

Design patterns are meta structures that you use when approaching a very specific kind of problem.

The examples I have presented here are in typescript, but you can transfer them to pretty much any other language.

The two patterns you must know - 

  • Observer
  • Iterator

The Observer Pattern

An Observer pattern is where you have an Observable where you observe something and call a method called notify as an event occurs.

All the update methods in the Observers associated with the Observable are called whenever the notify is triggered by the Observable.

The pattern classes- 

interface Observer {

  update(e: any): void;


abstract class Subject {

  observers: Observer[] = [];

  attach(ob: Observer) {



  notify(e) {

    this.observers.forEach(observer => {





Concrete implementations - 

class LoggerObserver implements Observer {

  update(e) {

    console.log('logger', e);



class DoubleLoggerObserver implements Observer {

  update(e) {

    console.log('double logger', e);

    console.log('double logger', e);



Usage - 

const inputElement: HTMLElement = document.getElementById("sample");

class FormInputSubject extends Subject {

  constructor(el: HTMLElement) {


    el.addEventListener("keydown", event => {





const formObservable = new FormInputObservable(inputElement);

formObservable.attach(new DoubleLoggerObserver());

formObservable.attach(new LoggerObserver());

If you look at the usage - you will see that FormInputObservable does not contain any code regarding what happens when the event occurs

This is exactly what the Observer pattern does -
it helps decouple an event from what is to happen when the event occurs.

Working Sample -

The Iterator Design Pattern

The iterator pattern is used to traverse a collection, where the underlying data structure may be anything ( an array, tree etc ).

Say you have a tree data structure. 

You can traverse this in many ways - depth first, breadth first etc

Having an uniform way to traverse this is what the iterator pattern provides you.

interface AIterator<T> {

  // Return the current element.

  current(): T;

  // Return the current element and move forward to the next element.

  next(): T;

  // Return the key of the current element.

  key(): number;


The concrete implementation - 

class NumberArrayIterator implements AIterator<number> {

  arr: number[];

  currentIndex: number;

  constructor(arr: number[]) {

    this.arr = arr;

    this.currentIndex = -1;


 next(): number {

    if (this.arr[this.currentIndex + 1]) {

      this.currentIndex = this.currentIndex + 1;

      return this.arr[this.currentIndex];


    return null;


  current(): number {

    return this.arr[this.currentIndex];


  key(): number {

    return this.currentIndex;



const a = new NumberArrayIterator([1, 2, 3, 4, 5]);

while ( {



The iterator pattern is awesome in the sense that you can think of anything you want to iterate on and model it in this format.

Working Sample -

Now, back to Rxjs.

Rxjs is based around something called an Observable. 

An Observable in Rxjs is basically a combination of the Observer and Iterator.

To create an Observable

const ob$ = new Observable(subscriber => {;;;;

   // it doesn't matter if this set interval goes on forever. An observer stops emitting once it has     completed

    setInterval(()=> {
    }, 100);

   setTimeout(()=> {


const sub1 =  ob$.pipe(

  filter(x => x/2)

).subscribe(val => {
  console.log(‘first’, val);

const sub2 = ob$.subscribe(val => {
  console.log(‘second’, val);

  console.log(‘second’, val);

Like the Observer design pattern - an Observable decouples the creation of the events from how you would handle them.

And it allows you to process the events that would come from this observable in the form of a stream - similar to the iterator pattern.

The subscribe is nothing but a for Each on events that arrive over time till the iterator reaches its end or the subscription is stopped manually.

This gives rise to a very powerful pattern that you can use the stream of events that arrive over time and mould them using operators - similar to how you use map, filter and reduce on arrays.

 For a in depth study, I would highly recommend


Aiyush Dhar

I am a Member of Technical Staff at Fyle. Beyond work, I find solace in video games, blogging, and my hot cup of ginger lemon tea.

More of our stories from

Interview Experience: Backend Engineering Internship at Fyle

Wanna know the secret to crack backend engineering interviews? Learn them here and intern at Fyle!

The curse of being a Senior Engineer, how to deal with timelines, frustrations, etc

Being a good developer is 50% skill and 50% emotional support; here's my secret to balancing both at the right amount!

How did I build cropping of receipts in the mobile app?

Follow Yash's journey of what it takes to reduce manual work for our customers when receipts come in all shapes and sizes!

How did we increase Data Extraction accuracy by a whopping ~50%?

Wanna know the secret of data extraction, the complex machine learning models we use, the experiments we did? Read on...

The not so secret sauce of my work

From chaos to clarity, follow Chethan's not so secret sauce to excelling at work!

From Zero to Hero: The Policy Tests Journey!

The story of policy tests at Fyle

How Fyle changed my life from a naive intern to a confident Engineering Lead

A blogpost that documents Shwetabh's journey at Fyle.

Vikas Prasad @ Fyle

This document is a user guide to Vikas at work.

Gokul K's README

This document is a user guide to Gokul at work.


All Topics