In Angular we have many directives and ng-template, ng-content and ng-containers are those directives that can be used for content projections. they have their own use case and set of features that sets them apart.
ng-template: It defines a block that renders dynamically and using ng-template we can render the same code at multiple places in our component.
<div *ngIf = "count < 0; else noData">
Total Count is : {count}
</div>
<ng-template #noData>
<span>No Data Found</span>
</ng-template>
as you can see in the above code, code written inside ng-template will not execute until the count is greater than 0.
ng-container: ng-container is used to group elements without adding any new element in the DOM. It's often used with structural directives like ngIf, **ngFor and \ngSwitch.
One use case of ng-container is applying structural directives without wrapping them in another HTML element.
<h3>Total Records</h3>
<div *ngIf = "count < 0">
Total Records : {{count}}
</div>
In the above code if we want to apply *ngIf directive to h3 and div both then we need to wrap them in an element and if we use HTML element here then it will create an extra element in DOM but we don't want this so here ng-container comes into picture.
<ng-container *ngIf = "isPageLoaded">
<h3>Total Records</h3>
<div *ngIf="count < 0">
Total Records : {{count}}
</div>
</ng-container>
ng-content: ng-content is used to pass the content from the parent component to the child component, it allows the parent component to inject content in the HTML template of the child component.
<app-question>
<p>Passing the content from parent</p>
</app-question>
/** app.component.html**/
<ng-content></ng-content>
/** question.component.html
So we have seen use cases of three content projections in angular - ng-template, ng-container and ng-content.