Beside all-known and common tips about how to create a component in Angular, there're some advanced tips not everyone would tell or show you — not because nobody knows about them, or maybe some developers keep them as secrets? ;)

1. Make sure you always "display" it right

Even if you might not find it useful, but sometimes it can give you some big trouble.

You could be in a situation that can't understand why some Component's children or either the current Component – is not showing or positioned as it needs to be, due to this - you can spend a lot of time searching the problem, in the end, to find out that a simple display: block can "save your life."

Just develop a behavior out of this, and always add :host { display: block; } in component styles. It's not mandatory to be block - this is just a typical case; change it as you need, but make sure you always have it applied to your Component.

Pro Tip:

If you use ng to generate a component, there's a shortcut for that, add  --displayBlock option in your command, it should look like this ng generate component YourComponent --displayBlock.

2. @Hostbind the class attribute

This can seem a bit confused, but it does the job. With Web Components coming in, why not thinking about the Angular Component that's a simple div or another common element?

Do you have to add the classNames to children's components, or you can bind them to host and save space in Component's HTML?

Or at least to have the HTML cleaner? It would help if you thought about it.

I always do this whenever I have a parent element that holds all component HTML, for example, if this is the Component's HTML:

<div class="parent">
    <p>Lorem ipsum dolor</p>
</div>
Component's HTML example

I would rewrite it like this:

<p>Lorem ipsum dolor</p>
Component's HTML after rewriting example
export class MyComponent {
    @HostBinding('class') get hostClassNames(): string {
    	return `parent`.trim();
  	}
}
Component's Logic after rewriting example

Just make sure .parent class is available outside of the Component. Yes, I intentionally used template literals so you'll better understand the power of it ;)

3. ChangeDetection to OnPush

Change detection is a cool feature in Angular, but you must be very attentive to it, as it can cause you significant issues. Why change it to OnPush? Simple, you don't need to recheck the Component's HTML every time something is changing inside the Parent Component.

But wait for a second, is it means Angular won't automatically check the Component's HTML for changes? Yes, it won't be. You must tell Angular when you should check the component changes, or use a straightforward trick — myVariable$ | async — let me explain to you more about it.

To mark the Component to be checked, a typical case is — inject the ChangeDetectorRef class into Component — ( I'm not going to show you how to achieve it here, check the official documentation page for more info. )

Another simple trick is to use Observables and Async pipe, remember I wrote an article about one of the best practice sending HTTP requests in Angular – here's almost the same logic, but besides that, async pipe automatically marks the Component to be checked for changes.

Lets see an example:

@Component({
  selector: 'my-component',
  templateUrl: './my-component.component.html',
  styles: [`
	:host { display: block }
  `],
  changeDetection: ChangeDetectionStrategy.OnPush,
  // See next section about exportAs metadata
  exportAs: 'myComponent'
})
export class MyComponent {
    myVariable$ = new BehaviorSubject('I hold a simple string')

	changeMyVariable() {
    	myVariable$.next('I\'m changed and automatically updated in template')
    }
}
Component's logic with Observablesc
<p>{{myVariable$ | async}}</p>

<!-- Change the variable & mark component to be checked for changes -->
<button (click)="changeMyVariable()">Change the variable</button>
Component's HTML with async pipe

Hope you got the idea!

Pro Tip:

Angular CLI allows to change it automatically: ng generate component YourComponent --changeDetection=OnPush

4. Make use of exportAs metadata

exportAs metadata is another option that makes the Component looks more than advanced. With it, we can get, set, and call the Component's functions/variables outside the Component's scope. Thanks to the Angular Team ;)

For example, let's say we have a simple component:

@Component({
  selector: 'my-count',
  template: `
    <p>Inside component scope: {{count$ | async}}</p>
  `,
  changeDetection: ChangeDetectionStrategy.OnPush,
  exportAs: 'myCount'
})
export class MyCountComponent {
  count$ = new BehaviorSubject(0);
  get count(): number {
    return this.count$.getValue()
  }

  inc(): void {
    this.count$.next(this.count + 1);
  }
}
MyCount Component logic

Now, let's try to increase the count outside the component scope:

<my-count #count="myCount"></my-count>
<p>Out of component scope: {{count.count}}</p>

<button (click)="count.inc()">Increase</button>
App Component Template

Check this StackBlitz for a better example. Pay attention, we haven't used Angular @ViewChild decorator to get the my-count Component instance, and we just added some simple logic ONLY inside the template – That's awesome!

Now, imagine what you can do with CdkPortals and exportAs metadata! – no worry, I might create another article about it later on ;)

Thanks and see you in the next article!