Explanation
What you are doing is perfectly valid but you have not taken into consideration the scope of the template variables.
Using structural directives creates scopes/boundaries which block the usage of those variables, as you can see there: https://angular.io/guide/template-reference-variables#template-variable-scope
So to solve your problem in the way you want you need to work on your template and remove the usage of the *ngIfs
A Partial solution
The following code which just omits the *ngIfs works as you'd expect it to (naturally this is not a complete solution since your component without the *ngIfs just behaves differently from what you wanted):
<div>
<mat-accordion class="example-headers-align">
<mat-expansion-panel [expanded]="false" hideToggle>
<mat-form-field>
<input #empName matInput type="text" formControlName="empName" >
</mat-form-field>
</mat-expansion-panel>
<button mat-button (click)="add(empName.value)">Add</button>
</mat-accordion>
</div>
You can check it out in this stackblitz project: https://stackblitz.com/edit/angular-ivy-c64ppz?file=src/app/app.component.html (please ignore the console errors on the material components, those are not the point here :P)
A Possible Solution
One thing that would change your code in the smallest degree but allow you to keep your implementation could be to avoid the *ngIfs but hide the elements via css instead, as in the following:
Template:
<div>
<mat-accordion class="example-headers-align">
<mat-expansion-panel [expanded]="expended" hideToggle>
<mat-form-field [ngClass]="{'hidden': !expanded}">
<input #empName matInput type="text" formControlName="empName" >
</mat-form-field>
</mat-expansion-panel>
<button [ngClass]="{'hidden': !expanded}" mat-button (click)="add(empName.value)">Add</button>
</mat-accordion>
</div>
css:
.hidden {
display: none;
}
Again here's a stackblitz in which you can see it working: https://stackblitz.com/edit/angular-ivy-iamrut?file=src/app/app.component.html
</div>that breaks your template there