enbma
enbma

Reputation: 75

FormControl element undefined once ngIf is placed on form element

i have a child component dynamically created inside a parent that handles the <form> group. The child looks like the following:

<div>
    <input [name]="name" #password="ngModel" required [(ngModel)]="pendingAccount.Password" />
    <input *ngIf="withPasswordRepeat" name="repeatedPassword" #repeatedPassword="ngModel" required  [(ngModel)]="pendingAccount.RepeatedPassword" />
</div>
<div *ngIf="!password.valid || (repeatedPassword !== undefined && !repeatedPassword.valid)">this is invalid...</div>

Even though both input fields are shown repeatedPassword keeps undefined whereas password is fine and hence the validation does not work as expected. But when looking at the NgForm Object that is being maintained by the parent component, the repeatedPassword FormControl is part of the NgForm object.

When i remove the *ngIf directive everything works as expected when it comes to showing the this is invalid... text.

So from the typescript perspective everything works but once *ngIf is applied, it seems like repeatedPassword keeps undefined and accessing repeatedPassword in the template (e.g. {{repeatedPassword}}) is not possible.

Can anybody explain to me why this is the case and is there is any solution without getting rid of the *ngIf directive?

Thanks in advance, best regards

Upvotes: 0

Views: 1597

Answers (2)

evilstiefel
evilstiefel

Reputation: 496

This doesn't work because #repeatedPassword is not known in the template when using *ngIf. If you write it out "desugared", it looks like this:

<div>
    <input [name]="name" #password="ngModel" required [(ngModel)]="pendingAccount.Password" />
    <ng-template [ngIf]="withPasswordRepeat">
      <input name="repeatedPassword" #repeatedPassword="ngModel" required  [(ngModel)]="pendingAccount.RepeatedPassword" />
    </ng-template>
</div>
<div *ngIf="!password.valid || (repeatedPassword !== undefined && !repeatedPassword.valid)">this is invalid...</div>

As you can see, your reference variable is only available inside the ng-template, so you can't use it outside of that environment. To avoid this problem, have a look at reactive forms. A "cheap" solution would be to not remove the element using *ngIf but rather just hide it visually using CSS.

Upvotes: 1

rehan meer
rehan meer

Reputation: 38

i am not sure whats the actual problem but i guess with a slight modification in the code we can achieve what you are looking for.

<div>
<input *ngIf="!withPasswordRepeat" [name]="name" placeholder="test" #password="ngModel" 
required [(ngModel)]="pendingAccount.Password" />
<input name="repeatedPassword" placeholder="test2" #repeatedPassword="ngModel" required  
[(ngModel)]="pendingAccount.RepeatedPassword" />
</div>

check out the working stackblitz: https://stackblitz.com/edit/ngif-fqwp2b

consider accepting the answer if alright :)

Upvotes: 0

Related Questions