Three Main Components in Reactive Programming

Three Main Components in Reactive Programming

An introduction to 3 components of reactive programming — producer, consumer, and data pipeline. Producers. Consumers. Data pipeline.

This article is about fundamental knowledge for components in reactive programming.

  1. Producers
  2. Consumers
  3. Data pipeline

The graph below demonstrates how reactive programming works in the big picture.


generic model from upstream observable to downstream observer in reactive programming

Producers

Producers are the sources of your data.

A stream must always have a producer of data, which will be the starting point for any logic that you’ll perform in RxJS.
A stream is nothing more than a sequence of events over time

The observer pattern defines producers as the subject. We call them observables, as in something that’s able to be observed.

Observables are in charge of pushing notifications, so we refer to this behavior as fire-and-forget. This means that we’ll never expect the producer to be involved in the processing of events, only the emission of them.

Consumers

Consumers are the components that accept events from the producer and process them in some way. When the consumer begins listening to the producer for events, you now have a stream. It is at this point that the stream begins to push events; we’ll refer to a consumer as an observer.

Streams travel only from the producer to the consumer.


consumer sample in rxjs

From the example above, whenever the user clicks on the submit button, it will produce an event that flows down to consumers.

In nature, a stream will flow from upstream to downstream; this same thing happens in reactive programming. The streams will always flow from the upstream observable to the downstream observer.

The click action from the user would be the upstream observable because it would only produce events, not consume them. And the code that executes logic based on the click action would be the downstream observer.

Data pipeline

The biggest benefit of reactive programming is you can edit the data as it passes from producer to consumer.

From one of my recent article is Reactive Programming in a Modern Web Application, I mentioned:

It combines the Observer pattern with the Iterator pattern and functional programming with collections to fill the need as an ideal way of managing sequences of events.

Functional programming? Yes, that is why we can find many functional programming syntax implementations inside libraries like RxJS.

To create a data pipeline, we use the pipable operator and operators that are provided by the RxJS library to transform data from producer to consumer by using functional programming.


data pipeline sample in rxjs

The producer will emit an array of users with name and age information via the data pipeline and the **pipe** operator, use map to transform data from the producer, and return to the consumer with the name of the user only.

Summary

This article provided basic knowledge on components in reactive programming. We have 3 parts which are the producer, data pipeline, and consumer.

Trick or Unsubscribe in RxJS: a Custom Angular Decorator

Trick or Unsubscribe in RxJS: a Custom Angular Decorator

One of the first concepts of Angular is Functional Reactive Programming via Observables. Angular extensively use Observables through RxJS library that introduces an implementation of the Observable type.

Background

Why Observables might be dangerous for your application? What are the options to reduce the risks? As you may have already guessed I’m going to talk about the “unsubscribe()” and I’ll be honored to present you my custom solution that is saving my lifetime and might save yours.

Introduction to Observable’s world

One of the first concepts of Angular is Functional Reactive Programming via Observables. Angular extensively use Observables through RxJS library that introduces an implementation of the Observable type. I won’t elaborate on the subject of Reactive Programming in the Angular or the RxJS library, I will just cover a few high-level principles.

According to official docs - “Observables are lazy Push collections of multiple values”. Other words to say, it is a data stream - a sequence of any values in time. So, an Observable is some kind of advanced Promise that pushes (resolves) multiple values over time to callbacks instead of only one value.

In order to notify the Observable when to send data and also react to new data in the future, we need to subscribe to it, by simply calling the “subscribe()” method. As I have mentioned above, the Observable is some kind of a stream itself what means that after subscribing to it, its execution will be infinite. And in order to cancel/complete it and “sleep like a baby”, we have simply to call an “unsubscribe()” method. Easygoing, right?

However, here’s the most common mistake, especially among juniors, when a developer simply forgets to unsubscribe from a stream and moves further. And an Observable that isn’t used anymore still would be producing values. That directly leads to tremendous memory leaks and unpredictable behavior of your application in the future.

What are the "advanced" options to unsubscribe?

As I have mentioned above, if you don’t want to shoot yourself in a leg - you always should remember to unsubscribe! The most common place to do it in Angular is inside of “ngOnDestroy” lifecycle hook that is executed by Angular once the component is not used anymore.

This is the easiest solution when you have one or two subscriptions but in the real Angular application, you have dozens of subscriptions. And definitely, it would be tedious each time to unsubscribe “manually”. What to do then? Let’s consider some "advanced" built-in ways of unsubscribing from multiple Observables:

1. Chained subscriptions:

As a Subscription is a Class that essentially has an “unsubscribe()” method, it also has an “add()” method. It allows "adding" one Subscription into another - a child subscription to a parent subscription. Thus, you need to call an unsubscribe() method only once - a parent Subscription unsubscribes all child Subscriptions. Have a look at the example below.

export class HomeComponent implements OnInit, OnDestroy {
  sub: Subscription = new Subscription();

constructor(
private invoicesService: InvoicesService,
private productsService: ProductsService,
private customersService: CustomersService,
) {
}
ngOnInit() {
this.sub
.add(
this.invoicesService.invoices$
.subscribe(invoices => console.log(invoices))
)
.add(
this.productsService.products$
.subscribe(products => console.log(products))
)
.add(
this.customersService.products$
.subscribe(products => console.log(customers))
);
}
ngOnDestroy() {
this.sub.unsubscribe();
}

However, there’s an adverse effect within chaining - in case one of the chained subscriptions completes, e.g. the products$ stream throws an error, then its further descendant, I mean the customers$ stream, won’t be executed. Thus, I’d suggest avoiding chaining.

2. An array of Subscriptions:

Firstly, we create a variable with type “Subscription[]”, e.g. “subscriptions” with initial value as an empty Array. Then we create a setter in order not to wrap manually each Subscription in a “push” construct. Afterward, in the ngOnDestroy lifecycle hook we simply call the forEach() method on our Array and call an unsubscribe() method on each subscription inside of it. Check out the code example:

export class HomeComponent implements OnInit, OnDestroy {

subscriptions: Subscription[] = [];

private set sub (sub: Subscription) {
this.subscriptions.push(sub);
}

constructor(
private invoicesService: InvoicesService,
private productsService: ProductsService,
) {
}

ngOnInit() {
this.sub = this.invoicesService.invoices$
.subscribe(invoices => console.log(invoices));

this.sub = this.productsService.products$
  .subscribe(products => console.log(products));

}
ngOnDestroy() {
this.subscriptions.forEach(sub => sub.unsubscribe());
}
}

3. RxJS “Subject” and “takeUntil” operator:

Firstly, we create a variable/stream, e.g. unsubscribe$ with a new instance of the RxJS Subject. Then inside of the pipe chain of any other stream, we declare the “takeUntil” operator to which we simply pass our unsubscribe$ stream. Afterward, in the ngOnDestroy lifecycle hook, we call next() and complete() callbacks on our Subject. It means that all subscribers automatically stop receiving future values when our Component would be destroyed because our Subject would be completed. Let me provide you with a code example:

export class HomeComponent implements OnInit, OnDestroy {

unsubscribe$: Subject<void> = new Subject();

constructor(
private invoicesService: InvoicesService,
private productsService: ProductsService,
) {
}

ngOnInit() {
this.invoicesService.invoices$
.pipe(
takeUntil(this.unsubscribe$)
)
.subscribe(invoices => console.log(invoices));

this.productsService.products$
  .pipe(
    takeUntil(this.unsubscribe$)
  )
  .subscribe(products =&gt; console.log(products));

}

ngOnDestroy() {
this.unsubscribe$.next();
this.unsubscribe$.complete();
}
}

4. RxJS “AsyncPipe”:

This is the last, however, the most reliable, neat and correct built-in option for unsubscribing within Observables. An “AsyncPipe” automatically subscribes to an Observable, returns the latest value it has emitted and also unsubscribes when a Component is destroyed. Thus, we don’t need to do anything. All the cleanup logic for avoiding the memory leaks is done under the hood. It’s amazing! Just take a look at an example below:

export class InvoicesComponent implements OnInit {

invoices$: Observable<Invoice[]>;

constructor(
private invoicesService: InvoicesService,
) {
}

ngOnInit() {
this.invoices$ = this.invoicesService.invoices$;
}
}
<main class="invoices-main">

&lt;mat-table [dataSource]='invoices$ | async'&gt;

....
</mat-table>

<main/>

Why have I come to a custom solution and what are the decorators itself?

The AsyncPipe is reliable and works well, however, very often we have to not just simply subscribe to an Observable and render the output, we need to put some logic in a subscribe() method. Thus, every time we’ll have to repeat the implementation in our Components one of those advanced unsubscribing options mentioned above.

So, after a while, I’ve decided that I don’t want to do a “monkey job” inside of many Components manually. I thought that it would be great to put out all the unsubscribing logic somewhere in one place and just reuse it when I would need, additionally to make my code cleaner and maintainable. And, thanks to the Typescript, I’ve found the right, neat and “Angularish” place - a Decorator. You might already know that Decorators are extensively used throughout an Angular, but if you don’t know what are the Decorators itself and asking yourself what is the magic under the hood, let me explain it very briefly.

In general, the main idea of Decorator is that you can dynamically attach to the object additional functionality. And if to be more precise, in a Typescript, the Decorator is a pure function with arguments that is called by @ sign and can be attached to:

  • Classes;
  • Methods;
  • Properties;
  • Parameters;
  • Accessor.

Just in case, here’s a simple example within a Class:

function Log() {
console.log(arguments);
}

@Log
export class HomeComponent {
...
}
// printed to console:
// {'0': [Function: HomeComponent]}

All in all, Decorators simply help to customize the thing they are attached to at design time. Let’s move further where I would be glad to present and describe my own Decorator for unsubscribing from Observables that I’ve called - “DestroySubscribers”.

My custom @DestroySubscribers() decorator

I’m really delighted with RxJS, but I’ve decided to automate the unsubscribe process and clean my code with the help of a Class Decorator and an “Array of Subscriptions” approach implementation.

Check out the “DestroySubscribers” Decorator itself:

export function DestroySubscribers(params?) {

return function (target) {
params = {
destroyFunc: 'ngOnDestroy',
...params
};
const unsubscribableLike: {subscriptions: Unsubscribable[], unsubscribe: () => void} = {
subscriptions: [],
unsubscribe,
};
const subscriber: string = Reflect.getMetadata('subscription:name', target.prototype, 'subscriber');

Object.defineProperty(target.prototype, subscriber ? subscriber : 'subscriber', {
get: () => unsubscribableLike,
set: subscription => unsubscribableLike.subscriptions.push(subscription),
});

if (typeof target.prototype[params.destroyFunc] !== 'function') {
throw new Error(${target.prototype.constructor.name} must implement ${params.destroyFunc}() lifecycle hook);
}

target.prototype[params.destroyFunc] = ngOnDestroyDecorator(target.prototype[params.destroyFunc]);

function ngOnDestroyDecorator(f) {
return function () {
unsubscribe();
return f.apply(this, arguments);
};
}

function unsubscribe() {
do {
const sub: Unsubscribable = unsubscribableLike.subscriptions.shift();
if ( sub && typeof sub.unsubscribe === 'function') { sub.unsubscribe(); }
} while (unsubscribableLike.subscriptions.length);
}

return target;
};
}

export function CombineSubscriptions(params?) {
return function (target, propertyKey: string | symbol) {
Reflect.defineMetadata('subscription:name', propertyKey, target, 'subscriber');
};
}

As you can see from the code above - the “@DestroySubscribers()” Decorator represents an “Array of subscriptions” approach extended with the “@CombineSubscriptions()” Decorator, and everything is done under the hood now. Let me briefly describe its main code points.

First, I’ve created an object with an empty array for future Subscriptions and custom unsubscribe method in order to have an ability to unsubscribe from all subscriptions at a time manually. Then with the help of reflect-metadata library and “@CombineSubscriptions” Decorator, I‘ve got the current property name from the Class or assign the “subscriber” as a default name and create getter and setter methods. Afterward, I’ve created another version of ngOnDestroy lifecycle hook that firstly unsubscribes from all subscriptions in the array, secondly invokes and returns the original ngOnDestroy method by default or another “destroying function” specified in the passed config to Decorator. That’s it - quite concise and easy to use.

And the decorator's implementation is even simpler. Check it out:

@DestroySubscribers({
destroyFunc: 'ngAfterViewInit',
})
export class HomeComponent implements OnInit, AfterViewInit {

/*
Within the @CombineSubscriptions Decorator, you can choose any custom name that you prefer.
Without the @CombineSubscriptions Decorator, the name by default is 'subscriber'.
*/
@CombineSubscriptions()
private subscriber: Unsubscribable;

constructor(
private invoicesService: InvoicesService,
private productsService: ProductsService,
) {
}

ngOnInit() {
this.subscriber = this.invoicesService.invoices$
.subscribe(invoices => console.log(invoices));

this.subscriber = this.productsService.products$
  .subscribe(products =&gt; console.log(products));

}

/*
This method must be declared, even if it's empty.
Otherwise, the Decorator would throw an Error.
*/
ngAfterViewInit() {
console.log('for unsubscribing');
}
}

The DestroySubscribers Decorator’s main definitions:

  • “subscriber” - a variable that represents the name by default for each subscription and conforms to an Unsubscribable Interface. Each time when you assign a Subscription to the "subscribe" variable - it's auto pushed to the array of Subscriptions under the hood. In addition, if you want to unsubscribe from all subscriptions at a time manually before a Component destroys, you can call an unsubscribe() method on the "subscriber" variable.
  • “@CombineSubscriptions()” Decorator - implement this Decorator in case you want to change the default variable's name("subscriber") of a subscription and use your own custom name, otherwise don't apply it.
  • {destroyFunc: '...' } - add this parameter to the “@DestroySubscribers” Decorator with the name of a hook for auto unsubscribing in case you want to change the default one - "ngOnDestroy" lifecycle hook, otherwise don't apply it. An ability to change the function called when a Component is destroyed gives you an opportunity to use this Decorator not only within an Angular.

The DestroySubscribers Decorator’s implementation steps:

Firstly, you have to annotate the Class with the “@DestroySubscribers()” Decorator.

Secondly, you need to create a variable called “subscriber” by default with the type Unsubscribable or if you want to use your own custom name - simply annotate that variable with “@CombineSubscriptions()” Decorator.

Thirdly, you should just assign to that variable each Subscription that you want to be unsubscribed from when the Component would be no longer in use.

The last thing, you must declare the ngOnDestroy lifecycle hook in a Component even if it's empty because of AOT compilation. Otherwise, the Decorator would throw an Error. In case you change the default lifecycle hook(ngOnDestroy) to another one(ngAfterViewInit) as in an example above, then this method must be declared in a Component, and the ngOnDestroy is obviously optional. I’ve told you, as easy as falling off a log!

Conclusion

All in all, I would like to outline that Decorators itself are nothing to be scared of, but rather are really amazing tools that you should use. They definitely would make your code more reusable, concise and readable!

In addition, thanks to the Angular community over time appeared many different solutions for unsubscribing. All of them are noteworthy and make our everyday lives easier! 

Thanks for reading. If you liked this post, share it with all of your programming buddies!

This post was originally published here

Angular and The Case for RxJS

Angular and The Case for RxJS

Angular and The Case for RxJS. When choosing Angular to build a front end app, it can seem like RxJS is just one more thing to learn, and there’s no easy transition coming from another framework. RxJS is a core part of the Angular framework used in everything from Reactive Forms to the HTTP module. evelopers can overcome the RxJS learning curve by focussing on core concepts like hot vs cold observables, piping operations, and a few of the most common operators.

When choosing Angular to build a front end app, it can seem like RxJS is just one more thing to learn, and there’s no easy transition coming from another framework. But RxJS is efficient and expressive! We declare relationships between entities, describing the what not the how. The basic sequence operators, map, filter, and reduce, are probably familiar from using them in array chains. RxJS is a core part of the Angular framework used in everything from Reactive Forms to the HTTP module.

Harnessing observables with Angular’s async pipe is essential to building clean and concise components. Developers can overcome the RxJS learning curve by focussing on core concepts like hot vs cold observables, piping operations, and a few of the most common operators.

Node vs Angular : Comparing Two Strong JavaScript Technologies

Just from being a simple client-side scripting language, JavaScript has evolved over the years to turn out to be a powerful programming language. Here Node.js is a cross-platform runtime environment while AngularJS is one of the top JavaScript framework. Angular helps the developers to build web applications which are dynamic in nature using HTML template language and following the MVC design pattern.