Sibling-relationship in Angular
Tags: javascript, angular, rxjs
Published: 2021-01-20 08:54:58

---
title: Sibling-relationship in Angular
published: true
description: "There are different approaches to manage the state and events between different components in Angular: let's see the method via RxJS and BehaviourSubjects!"
tags: ['js', 'javascript', 'angular', 'rxjs']
cover_image: https://www.stefanofrasca.com/static/09a57269bd88445b3033656f73497e32/angular-rxjs2.png
---

> You can see examples and more contents in [stefanofrasca.com](https://stefanofrasca.com/angular-rxjs-behavioursubj)

## Communication between components and state management

In a previous article, in stefanofrasca.com, I talked about publisher/subscriber architecture for what concerns webcomponent, and the approach used in <a href="http://www.maestrale.it/" target="_blank">Maestrale</a> for the management of <a href="./eventbus-javascript">communication between different web components</a> in our industry's 4.0 applications.

We also use **Angular and React** for projects of greater complexity and, although publisher/subscriber architecture and communication via EventBus is always a viable way to make components communicate with each other, adapting to the standards of frameworks or libraries we had to re-analyze the problem and use different approaches based on different use case of projects.

One of the most typical use cases, encountered almost daily, is when the components have 'to dialogue' not necessarily taking into account the hierarchically close relationship (parent -> child or child -> parent) but maintaining a generic common element that acts as a glue. In this case we speak of **'sibling-relationship'**.

## Angular e Directive

In **Angular** we model this approach using as **common component** a Directive that acts as a 'glue' for all the components that, through dependency injection, obtain the use of the Directive itself.

In analogy with the [webcomponent approach](https://www.stefanofrasca.com/eventbus-javascript) RxJS and the BehaviorSubject come to our aid.

We use the latter to maintain the application status (with private visibility within the Directive): the status update occurs by treating the **BehaviourSubject** [<sup><a href="https://www.learnrxjs.io/learn-rxjs/subjects/behaviorsubject" target ="_blank">ref</a></sup>] as Observable and exposing it
to components that need to get/update status.

Note that these components only have access to the BehaviorSubject (stream) Observable, not the BS itself!

Ultimately our Directive will deal with:

- Maintain the state
- Manage the status update via Observable (event stream [<sup><a href="https://rxjs-dev.firebaseapp.com/guide/observable" target="_blank">ref</a></sup>])

## A practical example!

For our example, let's use **colors** to describe the change of state: let's imagine 2 components interacting by changing a series of HEX values that we use to display the background and foreground colors of the same.
The state could therefore be represented by an object containing such values.

In our **directive** we instantiate and initialize the 'state' in the constructor through BehaviourSubject as Observable. Notice that we use a public 'updateColor' method that has access to the observable, then to the stream, to update the status.

```js
private colorBS = new BehaviorSubject({});
public colorObservable$ = this.colorBS.asObservable();

constructor() {
    //default
    const def = new ColorObject();
    def.bkg = "#D1DB44";
    def.frg = "#8B0000";
    ...
    ...
    this.updateColor(def);
}

updateColor(color: ColorObject) {
    this.colorBS.next(color);
}
```

There are then 2 components.

### color-bkg

Through the observable, the component takes care of showing the colors both in HEX and in RGB: in color$ I have the observable of the BehaviorSubject taken from the directive.
I use the observable as an async stream to access the 'state' and then show it.

```js
...
constructor(public directive: IntermediaryDirective) {}

ngOnInit() {
  this.color$ = this.directive.colorObservable$;
}
```

```html
<div *ngIf="color$ | async as color" [ngStyle]="{'background': color.bkg}">
  <span [ngStyle]="{'color': color.frg}">Changed color text?</span>
</div>
```

### color-picker

The component uses the observable to retrieve the 'state' and thus display the colors of the picker. In addition to this it calls the directive's 'updateColor' method to update the state, and then
notify the other components of the change (try to change color via picker!)

```js
...
constructor(public directive: IntermediaryDirective) {}

ngOnInit() {
  this.color$ = this.directive.colorObservable$;
  ...
}
updateBackground(val) {
  this.objColor.bkg = val;
  ...
  this.directive.updateColor(this.objColor);
}
```

```html
<ng-container *ngIf="color$ | async as color">
    <input
      #pickerbkg
      type="color"
      [value]="color.bkg"
      (change)="updateBackground(pickerbkg.value)"
    />
    ...
</ng-container>
```

> You can see examples and more contents in [stefanofrasca.com](https://stefanofrasca.com/angular-rxjs-behavioursubj)