Angular Material Source Code - Badge Component (Directive)
Tags: angular, angularmaterial, badge, webdev
Published: 2022-10-12 18:06:33

**Introduction**
This is a series of article on source code of Angular Material components. This series may look very crude with lot of images which will try to explain the content.

In this article will look at the Badge Component.

Link to the overview and source code respectively 
https://material.angular.io/components/badge/overview
https://github.com/angular/components/tree/main/src/material/badge


**Prerequisites**

1. Angular
2. Using Angular Material
3. Directives 
4. JavaScript

**Getting started**
Lets see How to use the Badge component and how DOM looks when it is rendered.



![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zy31w7altsgd5d9gak1p.png)

The badge ( i.e matBadge=4 and matBadge=1) is put inside the span element and also there are other input options available like matBadgeColor, matBadgeOverlap, matBadgeSize etc..

We will see how this extra span is created by the Angular Material Badge component and source code of other inputs of the component



1. **matBadgeColor** :
The value passed through this input is stored in the _color variable and same kind of class is attached to the host element (to which directive is attached) i.e using ElementRef ( This will give the reference of the host element, with the help of constructor injection ).


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wixniao8z0jrvc5ckzcg.png)

If you are using Badge directive on the div element, _elementRef will hold the reference of div element.

 
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/k1sr2rojb3str7nu4bhy.png)

Here nativeElement is accessed using _elementRef  and class is attached to the host element. This way you see primary, warning, accent badges


2 **matBadgeOverlap** : 
This input will decide how to place the Badge wrt to the host element. See first image you can observe 4 and 1 are placed different wrt to the div element

if overlap is set to true mat-badge-overlap class is set otherwise it is not.

This class is set using host property available with the @Directive 



![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/r8uei3zxb29ka7lspg6h.png)

One can observe the usage of coerceBooleanProperty function.
This will convert string | null | undefined | boolean to boolean value

i.e you can pass 
matBadgeOverlap="true" ==> true
matBadgeOverlap="false" ==> false
matBadgeOverlap=null ==> false
matBadgeOverlap=undefined ==> false
matBadgeOverlap="not false string" ==> true
matBadgeOverlap="1" ==> true


`cerceTOBoolean(value){
   value != null && `${value}` != 'false';
}`

In this function we are using loose equality operator, so value is converted to truty/falsy and also same with null

1.when value is false
falsy != falsy ==> **true**

2.when value is null
falsy != falsy ==> **true**

3.when value is "false"

truthy != falsy ==> true
and
"true" != "false" ==> **true**

3 **matBadgePosition**, **matBadgeSize**, **matBadgeHidden** : 
With the above info, I guess following above input is straight forward.

4 **matBadge**

will see how span is created and place inside the host element (ex: div element)

- create span element `this._renderer.createElement('span');`
- set id, class, attribute to the span element 
- `badgeElement.setAttribute('id', mat-badge-content-${this._id});`
- `badgeElement.setAttribute('aria-hidden', 'true');`
- `badgeElement.classList.add(BADGE_CONTENT_CLASS)`;`

- append the span to the host 
- `this._elementRef.nativeElement.appendChild(badgeElement)`


When ever this input value changes we need to update the content of the span, _updateRenderedContent is used to do the same.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/64we0qao89cur4bqb1fn.png)

if Badge is create (i.e is span is created) update the content otherwise create one and update the content.

That is all core stuff related to the Badge Component

**Take away points**

1. How to access the host element and its native html using ElementRef injection.
2. How to use the host property to add class, id etc to the host element.
3. How to convert the string | boolean | null | undefined to Boolean type.
4. How to create and append the element using required dependencies.
5. Use of static member to track the count of the objects created
6. advantage of @Input getter and setter over ngOnChange