5

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?

Kamil Naja
  • 6,267
  • 6
  • 33
  • 47
Chuvisco
  • 101
  • 1
  • 6
  • angular have elvis operator? or its just ignored – YOU Dec 20 '16 at 10:14
  • I tried to use price && price.invalid && price.dirty in the ngIf as well, which didn't help – Chuvisco Dec 20 '16 at 10:17
  • Yes @Chuvisco, I realized what you wanted to achieve, therefore I deleted my comment, but you had already replied to my comment, so it looks like you are talking to yourself now, sorry about that :D But yes, I understand what you meant now! – AT82 Dec 20 '16 at 10:40
  • Found http://stackoverflow.com/questions/30027244/passing-angularjs-ng-form-object-into-ng-if where `[hidden]` is used instead of `*ngIf`, which is a workaround in this case. Still it would be better to not have the input at all if the condition is not true – Chuvisco Dec 20 '16 at 10:53

2 Answers2

0

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.

Milad
  • 27,506
  • 11
  • 76
  • 85
  • I tried that as well, with no luck so far. It seems as soon as I use an `*ngIf` the #price is not updated anymore and it does not matter if it on the input or on the container around it. For your second point, true that, in this slimmed down example it is only with required. – Chuvisco Dec 20 '16 at 13:11
-1

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.

Kyle Burkett
  • 1,375
  • 12
  • 28