DEV Community

Cover image for The Little Component That Could
ng-conf
ng-conf

Posted on

The Little Component That Could

Maria Korneeva | ng-conf | Jan 2022

A tale of a flexible Angular component - or when to use input or content projection

Once upon a time, there was a little ChameleonComponent. He was really tiny but very determined. According to the single responsibility principle, he could only stay green, as he was spending all his time in green woods. Here he is:

ChameleonComponent.html:
<p>I am a little green chameleon.</p>
ChameleonComponent.ts:
export class ChameleonComponent {}
Enter fullscreen mode Exit fullscreen mode

Some day our little chameleon decided to go for a walk. It was a nice summer day, and he was heading further and further and further. Suddenly, he found himself in the middle of the red-flowered field. Some birds have spotted him and were circling around, coming closer and closer. “Oh my…” — thought our little chameleon. Luckily, he heard his mother screaming: “Hide, why can’t you hide?!” She waved at him:

ParentChameleonComponent.html:
<chameleon-component [isHiding]="isChildInDanger"></chameleon-component>
ParentChameleonComponent.ts:
export class ParentChameleonComponent {
   public isChildInDanger = false;
   public screamChildInDanger(){
      this.isChildInDanger = true;
   }
}
Enter fullscreen mode Exit fullscreen mode

“I think, I can hide. I think I can…” — thought our little friend and did the following:

ChameleonComponent.html:
<p *ngIf="isHiding; else greenColor">I am a little red chameleon.</p>
<ng-template #greenColor>I am a little green chameleon.</ng-template>
ChameleonComponent.ts:
export class ChameleonComponent implements OnChanges {
   @Input() public isHiding: boolean;
   public color = ‘green’;
   ngOnChanges(): void {
      if (this.isHiding) {
         this.color = ‘red’;
      }
   }
}
Enter fullscreen mode Exit fullscreen mode

“But darling, it’s not enough to be just red or green” — his mother said. “What if you are sitting on some yellow or blue flowers? You should be able to change to any color.” “I think, I can…” — said the little chameleon thoughtfully. That is what he adjusted:

ChameleonComponent.html:
<p>I am a little {{ color }} chameleon.</p>
ChameleonComponent.ts:
export class ChameleonComponent {
   @Input() public color: string;
}
Enter fullscreen mode Exit fullscreen mode

So, his mother had no longer to tell him to hide, but just told him which color to use:

ParentChameleonComponent.html:
<chameleon-component [color]="chameleonColor"></chameleon-component>
ParentChameleonComponent.ts:
export class ParentChameleonComponent {
  public chameleonColor: string;
   public changeChildColor(){
      this.chameleonColor = this.getTheColorOfSurroundings();
   }
}
Enter fullscreen mode Exit fullscreen mode

And so our chameleon went on discovering different fields and woods. Yet one thing kept bothering him: why would he admit that he is a chameleon when hiding? Wouldn’t it be even better to distract from his being, let’s say, by stating, that he is a HUGE TIGER? “Good idea!”, — said his mom. The little chameleon rearranged himself the following way:

ChameleonComponent.html:
<ng-content></ng-content>
ChameleonComponent.ts:
export class ChameleonComponent {}
Enter fullscreen mode Exit fullscreen mode

His mom could now not only show him how to change the color but also texture or even complete insides — turning into a tiger (attack is the best defense, you know…).

ParentChameleonComponent.html:
<chameleon-component>
   <h1>I'M A HUGE TIGER!!!</h1>
</chameleon-component>
ParentChameleonComponent.ts:
export class ParentChameleonComponent {...}
Enter fullscreen mode Exit fullscreen mode

black and white image. the background is mostly black with a grouping of black, sketch style flowers in the middle. Overtop the flowers is a simple white line art chameleon, the flowers

Our little chameleon was from now on safe and in perfect disguise! “Someday, when you grow up, you will be able to set your own color and insides”, — said his mother. “Then you will become a true Web Component”.

The End.

Afterword

As Jeremy Elbourn said in his talk “A Philosophy for Designing Components with Composition”,

“Customization is inevitable, so build for flexibility”.

However, you have to decide, which degree of flexibility you really need:

  • A component doing just one job in all use cases,
  • A component that has a limited number of options (selection),
  • A component that should display any information with the given structure,
  • A component that should display any information with flexibly structure.

Here are some useful reads on the topic:

Angular: Angular is a platform for building mobile and desktop web applications. Join the community of millions of developers…

Angular ng-content and Content Projection - The Complete Guide: One of the Angular features that help us the most in building reusable components is Content Projection and ng-content…

My special thanks goes to Hendrik for spontaneous and yet very fruitful conversation which indirectly sprouted this article.


ng-conf: The Musical is coming

ng-conf: The Musical is a two-day conference from the ng-conf folks coming on April 22nd & 23rd, 2021. Check it out at ng-conf.org


[Disclaimer: did I miss something / is something not quite correct? Please let me and other readers know AND provide missing/relevant/correct information in your comments — help other readers (and the author) to get it straight! a.k.a. #learningbysharing]

Top comments (0)