Angular Beginner's guide - Passing data within an application
Tags: angular, beginners, rxjs, frontend
Published: 2023-04-04 11:57:09

---
title: Angular Beginner's guide - Passing data within an application
published: true
description: Angular - Behaviour Subject - What i wish i knew as a beginner Angular developer
tags: #angular #beginner #rxjs #frontend
# published_at: 2023-04-04 07:16 +0000
---

## Introduction 

I started developing in Angular four years ago with my team. There are several concepts I wish I knew at the beginning. And this one is probably the main subject. I hope this can be helpful to anybody that would start working with angular.

## What is it and why use Behaviour Subject

Behaviour subject is a component from the RxJx library. You can check the documentation here :
[RxJs Behaviour Subject Documentation](https://www.learnrxjs.io/learn-rxjs/subjects/behaviorsubject)

A behaviour subject is basically an object that emits the current value to new subscribers.

So If you have a data structure, object or variable you want to share all the way through your application, this will be very useful.

## Our Application example

So I created a new Angular project, and i added three components to create our main page.
It is a very simple application. So our page will have a header with a save button, a metadata part with an input text and a content part with a textarea. Of course this could be way more complex but the goal here is to show the principle of the behaviour subject.

What we would like to do is to disable the save button in the header when the metadata field and the content field are not filled.
All the source code can be found at this repository : 
[Source code in GitHub](https://github.com/OppySB/behaviour-subject.git)


![Application look](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/k6ogdqntjk07jyhbsvu8.png)

## Scafolding the components

For our page, we create a main component create-article, and inside this component we create our three components : header, metadata and content.

![Scafolding components](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/n10bhzesq3xv9kd21u7o.png)

I created a **common** folder to put in the services and models and everything that could be common or shared between the different components.
We put a model **Article** and a service for the state of the article. 

![Article state service](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/m6pty2cud0jabcpbda24.png)
## The Article and Article state

Our article interface, with the data from the metadata and content.

```javascript
export interface Article {  
  
    /**  
     * the medata Infos     
     */    
     metadata?: string;  
  
    /**  
     * content field     
     */    
     content?: string;  
  
}
```

And our article state class will look like this :

```javascript 
import { Injectable } from '@angular/core';  
import { BehaviorSubject } from "rxjs";  
import { Article } from "../model/Article";  
  
@Injectable({  
    providedIn: 'root'  
})  
export class ArticleStateService {  
  
    public readonly selectedArticleState$ = new BehaviorSubject<Article>([] as Article);  
    private selectedArticleState: Article = {} as Article;  
  
    public constructor() {  
    }  
  
    /**  
     * set the current article     
     * @param value  
     */  
    public setSelectedArticleState(value: Article): void {  
        this.selectedArticleState = value;  
        this.selectedArticleState$.next(this.selectedArticleState);  
    }  
  
    /**  
     * Get the current article    
     */    
     public getSelectedArticleState(): Article {  
        return <Article>this.selectedArticleState;  
    }  
}
```

By convention, we suffix the behaviour Subject with a $. This behaviour subject is used to send the data to its subscribers. We use the **selectedArticleState** for storing the current Article value inside the class.
We also have a setter and a getter.


## Let use our article state

So in the main component **create-article**, in the **create-article-component.html**, we use our 3 sub-components :
```html
<app-header></app-header>  
<app-metadata></app-metadata>  
<app-content></app-content>
```

## Our header component

```javascript
import {Component, OnInit} from '@angular/core';  
import {ArticleStateService} from "../../common/service/article-state.service";  
import {Article} from "../../common/model/Article";  
  
@Component({  
    selector: 'app-header',  
    templateUrl: './header.component.html',  
    styleUrls: ['./header.component.scss']  
})  
export class HeaderComponent implements OnInit {  
    public disabled: boolean;  
  
    public constructor(public readonly articleStateService: ArticleStateService) {  
    }  
  
    public ngOnInit(): void {  
        this.disabled = true;  
        this.articleStateService.selectedArticleState$.subscribe((article: Article) => {  
            if (article.content && article.metadata) {  
                this.disabled = !(article.content.length > 0 && article.metadata.length > 0);  
            } else {  
                this.disabled = true;  
            }  
        });  
    }  
}
```
When the component is initialized, we subscribe to the behaviour subject, so anytime the article change, we will get here the current article. 
For our application, we can set the **disabled** variable to the right value, depending on the content and the metadata values.

## The setting of the article state


For example, in the metadata component we create a formGroup for the metadata field and when the value changes we set the current article from the state with its value.
```javascript
import {Component, OnInit} from '@angular/core';  
import {FormControl, FormGroup, Validators} from "@angular/forms";  
import {Article} from "../../common/model/Article";  
import {ArticleStateService} from "../../common/service/article-state.service";  
  
@Component({  
    selector: 'app-metadata',  
    templateUrl: './metadata.component.html',  
    styleUrls: ['./metadata.component.scss']  
})  
export class MetadataComponent implements OnInit {  
    public metadataForm: FormGroup;  
  
    constructor(public articleStateService: ArticleStateService) {  
	    // We create a formGroup for the metadata field
        this.metadataForm = new FormGroup({  
            metadata: new FormControl(  
                '', [Validators.required])  
        });  
    }  
  
    public ngOnInit(): void {  
        this.metadataForm.valueChanges.subscribe(formGroup => {  
	        // We get the current article with the article state service
            const article: Article = this.articleStateService.getSelectedArticleState();  
            // We set the metadata in the current article to the formGroup metadata value
            article.metadata = formGroup.metadata;  
            // We set it back in the state service as the current article
            this.articleStateService.setSelectedArticleState(article);  
        });  
  
    }  
}
```

## The end

I hope this post can be useful to anybody, beginner or not in Angular. You can find the unit tests for the components and service in the github repository.
Please let me know what you think. 
Do you use the behaviour subjects that way in your applications?
Do you have other ways of doing it ?