Angular 2 - How to get the valid state of input with ngIf

4k views Asked by At

I am trying to wrap my head around this problem for some time now.

When I try to have an input in a form only if a condition is true, I receive an error, that invalid could not be read from undefined.

When using the elvis operator I don't get the error anymore, but even if the input is displayed, invalid & dirty, I still don't see the error message.

<form #myForm="ngForm">
    ... other inputs ...

    <input *ngIf="model.type === 'V'" 
        name="price"
        type="number"
        required
        [(ngModel)]="model.price"
        #price="ngModel">
    <div class="errors" *ngIf="price?.invalid && price?.dirty">
        Problem detected
    </div>
</form>

Anyone a hint what I am missing?

2

There are 2 answers

1
Milad On

What I would do , I'd wrap the input and the error inside the first condition :

<form #myForm="ngForm">
   <div *ngIf="model.type === 'V'" >
       <input
           name="price"
           type="number"
           required
           [(ngModel)]="model.price"
           #price="ngModel">
        <div class="errors" *ngIf="price?.invalid && price?.dirty">
           Problem detected
       </div>
    </div>
</form>

This makes more sense , because you don't want the check for the error to fire if the input does not exist at all !

And the other thing is , the only validation you have is required , so as soon as you make this field dirty, it becomes valid, unless you delete your text.

0
Kyle Burkett On

There is another question on SO very similar here:

AngularJS ng-if and scopes

It's actually an issue with scope.

ngIf creates a child scope. If you want to bind an input in a child scope to an object in it's parent scope you have to first create an object to bind it to.

For example in your controller:

$scope.newObject = {type: '', price: ''};

Then inside the ngIf you can bind and reference the object that already exists.

<div ngIf = "newObject.type == 'V'"
     <input type="number" model="newObject.price" />
</div>

But you cannot create a new object in parent scope from child ngIf scope, so it's best to initialize this object in the controller so you can reference it in the child scope.