The Little Component That Could

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

Maria Korneeva
ngconf

--

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 {}

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;
}
}

“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’;
}
}
}

“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;
}

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();
}
}

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 {}

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 {...}

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:

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

[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]

Now that you’ve read this article and learned a thing or two (or ten!), let’s kick things up another notch!

Take your skills to a whole new level by joining us in person for the world’s first MAJOR Angular conference in over 2 years! Not only will You be hearing from some of the industry’s foremost experts in Angular (including the Angular team themselves!), but you’ll also get access to:

  • Expert panels and Q&A sessions with the speakers
  • A friendly Hallway Track where you can network with 1,500 of your fellow Angular developers, sponsors, and speakers alike.
  • Hands-on workshops
  • Games, prizes, live entertainment, and be able to engage with them and a party you’ll never forget

We’ll see you there this August 29th-Sept 2nd, 2022. Online-only tickets are available as well.

https://2022.ng-conf.org/

--

--

Maria Korneeva
ngconf
Editor for

Learning tech hacks by sharing them with you— that is what drives me. #learningbysharing