javascriptangulartypescriptangular-ng-if

Why is the code within my ng-template and ngIf not working properly


I have a method that should show the following HTML based on the method. However it's not working at all. Can anyone explain why my ngIf is being ignored?

        <div class="field">
            <label for="birthday">Birthday</label>
            <mat-form-field class="example-full-width">
                <mat-label>Choose a date</mat-label>
                <input matInput [matDatepicker]="picker" id="birthday" [formControl]="birthdayFormControl" (dateInput)="calculateAge()" (dateChange)="calculateAge()">
                <mat-hint>MM/DD/YYYY</mat-hint>
                <mat-datepicker-toggle matIconSuffix [for]="picker">
                </mat-datepicker-toggle>
                <mat-datepicker #picker></mat-datepicker>
            </mat-form-field>
        </div>
    </div>


<ng-template *ngIf="isApplicantMinor()"> // - not working
<div class="row">
    <div class="column">
        <div class="field">
            <label for="parentBirthday">Birthday</label>
            <mat-form-field class="example-full-width">
                <mat-label>Choose a date</mat-label>
                <input matInput [matDatepicker]="picker" id="parentBirthday">
                <mat-hint>MM/DD/YYYY</mat-hint>
                <mat-datepicker-toggle matIconSuffix [for]="picker">
                    <!--                        <mat-icon matDatepickerToggleIcon>keyboard_arrow_down</mat-icon>-->
                </mat-datepicker-toggle>
                <mat-datepicker #picker></mat-datepicker>
            </mat-form-field>
        </div>
    </div>
    <div class="column">
        <div class="field">
            <label for="birthday">Parent's Email Address</label>
            <mat-form-field class="example-full-width">
                <mat-label>Email</mat-label>
                <input type="email" matInput [formControl]="emailFormControl" [errorStateMatcher]="matcher"
                      placeholder="Ex. pat@example.com">
                <mat-hint>Enter your parents email!</mat-hint>
                <mat-error *ngIf="emailFormControl.hasError('email') && !emailFormControl.hasError('required')">
                    Please enter a valid email address
                </mat-error>
                <mat-error *ngIf="emailFormControl.hasError('required')">
                    Email is <strong>required</strong>
                </mat-error>
            </mat-form-field>
        </div>
    </div>
</div>
</ng-template>

In the TypeScript

isApplicantMinor(): boolean {
    this.applicantIsMinor = false;
    if (this.applicantAge < 18) {
        this.applicantIsMinor = true;
    }
    return this.applicantIsMinor;
}

 calculateAge() { // a date on string "22/10/1988
    //debugger;
    this.applicantIsMinor = false;
    var dateString = moment(this.birthdayFormControl.value).format("MM/DD/YYYY") || moment(new Date().toDateString()).format("MM/DD/YYYY");

    let age: number = 0;
    if (dateString === undefined || dateString?.length === 0) {
        dateString = new Date().toDateString();
    }
    var dateParts = dateString.split("/");
    var dateObject = new Date(+dateParts[2], +dateParts[0], +dateParts[1]);
    console.log(dateObject);

    if (dateString) {
        var timeDiff = Math.abs(Date.now() - new Date(dateObject).getTime());
        age = Math.floor(timeDiff / (1000 * 3600 * 24) / 365.25);
        console.log(age);
    }
    this.applicantAge = age;
    if (this.applicantAge < 18) {
        this.applicantIsMinor = true;
    }
    return age;
}

Solution

  • Replace ng-template with ng-container. The reason is *ngIf internally uses ng-template. Angular will desugars *ngIf structural directive syntax. Angular will move the element onto which the structural directive *ngIf was applied into a ng-template & will split the expression *ngIf into two separate directives,[ngIf] and [ngIfElse]