How to check whether ng-content is empty? (in Angular 2+ till now)
Wrap ng-content
in an HTML element like a div
to get a local reference to it, then bind the ngIf
expression to ref.children.length == 0
:
template: `<div #ref><ng-content></ng-content></div>
<span *ngIf=" ! ref.children.length">
Display this if ng-content is empty!
</span>`
Updated for Angular 12; old logic ("
ref.nativeElement.childNodes.length
") gives error, asnativeElement
isundefined
nowadays.
How to check whether ng-content exists
If you have a parent element of <ng-content>
with a template variable (#panelHeading
)
<div class="panel panel-default">
<div class="panel-heading" #panelHeading [hidden]="!showHeading">
<ng-content select="my-panel-heading"></ng-content>
</div>
<div class="panel-body">
<ng-content select="my-panel-content"></ng-content>
</div>
</div>
then you can query for it like
@ViewChild('panelHeading') panelHeading;
and set a property depending on whether there are children or not
constructor(private cdRef:ChangeDetectorRef) {}
showHeading:boolean = false;
ngAfterViewInit() {
this.showHeading = this.panelHeading.nativeElement && this.panelHeading.nativeElement.children.length > 0;
this.cdRef.detectChanges();
}
If <my-panel-heading>
is an Angular2 component, then you can also use
@ContentChild(MyPanelHeading) panelHeading:MyPanelHeading;
constructor(private cdRef:ChangeDetectorRef) {}
showHeading:boolean = false;
ngAfterViewInit() {
this.showHeading = this.panelHeading != null;
this.cdRef.detectChanges();
}
If ng-content has content or empty Angular2
Use children
instead of childNodes
. Angular creates comment nodes for *ngIf* which are counted by
childNodes`
<div #contentWrapper [hidden]="isOpen">
<ng-content ></ng-content>
</div>
<span *ngIf="contentWrapper.children.length == 0">
<p>Display this if ng-content is empty!</p>
</span>
Plunker example
How to provide a fallback for empty ng-content in Angular?
You can check for projected content yourself and show alternative content when none was found:
@Component({
template: `
<div *ngIf="hasContent">alternative content</div>
<div #wrapper>
<ng-content></ng-content>
</div>
`
})
class MyComponent implements AfterContentInit {
@ContentChild('wrapper') wrapper:ElementRef;
hasContent = false;
ngAfterContentInit() {
this.hasContent = this.wrapper.childNodes.length > 0;
}
}
Angular 8: detect if a ng-content has content in it (or exists)
In Angular 8 you dont have to use the ngAfterViewInit life cycle hook. You can use the ngOnInit as long as you set the "static" value of the viewchild to true.
import { Component, OnInit, ViewChild, TemplateRef, ElementRef } from '@angular/core';
@Component({
selector: 'app-test',
templateUrl: './test.component.html',
styleUrls: ['./test.component.scss']
})
export class TestComponent implements OnInit {
@ViewChild('content', { read: ElementRef, static: true }) content: ElementRef;
constructor() { }
ngOnInit() {
console.log(!!this.content.nativeElement.innerHTML); // return true if there is a content
}
}
Note that you must wrap the ng-content directive with html tag (such as div, span etc) and to set the templateRef on this outer tag.
<div #content>
<ng-content></ng-content>
</div>
I putted it on stackblitz: https://stackblitz.com/edit/angular-8-communicating-between-components-mzneaa?file=app/app.component.html
Related Topics
Sorting Objects by Property Values
Clearrect Function Doesn't Clear the Canvas
How to Reset <Input Type = "File">
How to Send an Ajax Request on a Different Port with Jquery
React.Js: Onchange Event for Contenteditable
Undefined Values in Array(Len) Initializer
How to Search JSON Tree with Jquery
What Is This Practice Called in JavaScript
Merge Two Arrays So That the Values Alternate
Leaflet Drawing Tiles Disjointly
Is Reading the 'Length' Property of an Array Really That Expensive an Operation in JavaScript
How to Automatically Reload a Page After a Given Period of Inactivity
Why Do We Need to Install Gulp Globally and Locally