1

The validation works but I always get the same error message linked with required when the input error is about min/max.

And another issue that the error message is only shown when i click outside the input first time.

component.ts

import { Component, OnInit, ChangeDetectorRef } from '@angular/core';
import { FormControl, Validators, FormBuilder, FormGroup} from '@angular/forms';

export class myClass implements OnInit {
    myform: FormGroup;

    constructor  (private _fb:FormBuilder){}

    public someAmount = new FormControl('', [Validators.required, Validators.min(10), Validators.max(300)]);

    ngOnInit():void {
        this.myform = this._fb.group({
            someAmount: ['', [Validators.required, Validators.min(10), Validators.max(300)]]
        });
    }
}

component.html

 <form novalidate [formGroup]="myform" class="col-sm-4 form-group">
     <md-input-container>
         <input mdInput id="amount"
                       name="someAmount"
                       formControlName="someAmount"
                       type="number"
                       class="form-control "
                       [(ngModel)]="amount"
                       placeholder="amount"
                       (keyup)="onAmountChange()"/>
         <md-error *ngIf="someAmount.hasError('required')">
             <span> number required </span>
         </md-error>
         <md-error *ngIf="someAmount.hasError('min')" class="top-margin-medium text-center bold alert-danger">
             <span>amount should be not less than 10 </span>
         </md-error>
         <md-error *ngIf="someAmount.hasError('max')" class="top-margin-medium text-center bold alert-danger">
             <span>amount should be not more than 300</span>
         </md-error>
     </md-input-container>
 </form>
Hazu
  • 105
  • 1
  • 11

3 Answers3

0

I think there are two main problems with the code above.

In your html you are referencing the variable 'useramount' which is nowhere defined in your component ( it is defined as someAmount ).

Futhermore, the formControl assigned to the someAmount variable is not linked to the form group, hence no errors/changes will be associated with it.

You need to adjust your component code as follows

 export class myClass implements OnInit {
     myform: FormGroup;
     useramount:AbstractControl;

     constructor  (private _fb:FormBuilder){}

     ngOnInit():void {
         this.myform = this._fb.group({
             someAmount: ['', [Validators.required, Validators.min(40), Validators.max(300)]]
         });
         this.useramount = this.myform.get('someAmount');
     }
}
JeanPaul A.
  • 3,613
  • 1
  • 20
  • 29
  • Thanks! It's my bad when writing the question here! in my code it's useramount instead of someAmount! i edited my code in the question so this issue is not the problem! but in this line this.someAmount = this.myform.get('someAmount'); method get doesn't seem to exist for FormGroup! it doesn't even build when i put this line! – Hazu Aug 04 '17 at 09:23
  • Something's wrong in that case. The get method is defined in the AbstractControl class, https://angular.io/api/forms/AbstractControl which is extended by the FormGroup class. – JeanPaul A. Aug 04 '17 at 12:25
0

Thanks to JeanPaul who pointed out that the formControl is not linked to the formGroup.

I was able to get it to work by doing this in my html:

   <md-error *ngIf="myform.controls['someAmount'].hasError('required')>
          <span> required error message </span>
   </md-error>
   <md-error *ngIf="myform.controls['someAmount'].hasError('min')>
          <span>min error message</span>
   </md-error>
   <md-error *ngIf="myform.controls['someAmount'].hasError('max')>
          <span>max error message</span>
   </md-error>
Hazu
  • 105
  • 1
  • 11
  • For me, this does not show the messages until you focus out https://plnkr.co/edit/Wuz0E9VWjOTrU5FhNmnl?p=preview from the input field, but maybe that's what you want :) But also consider removing the two-way-binding. It is redundant ;) But it's up to you :) – AT82 Aug 04 '17 at 10:45
  • @AJT_82 Thanks for your response! i see your point in the tow way binding! but i still don't get the messages till i focus out! what is the issue here? – Hazu Aug 04 '17 at 11:18
  • Apparently it's a bug (?) which you can hack. I wrote an answer earlier which I deleted when I saw your answer, but I undeleted that now and added the hack. Hope you don't mind the answer :) – AT82 Aug 04 '17 at 12:17
0

Change the validation messages to point to the formcontrol with the following *ngIf:

*ngIf="myform.hasError('required', 'someAmount')"
*ngIf="myform.hasError('min', 'someAmount')"
*ngIf="myform.hasError('max', 'someAmount')"

Furthermore...

While it's not explicitly stated in the docs that they ngModel and reactive forms should not be used together, we can gather from the fact that ngModel directive is not included in ReactiveFormsModule, that perhaps we shouldn't use them together :)

so I'd suggest you remove ngModel and only have the form control:

<input mdInput formControlName="someAmount"
               type="number"
               (keyup)="onAmountChange()"/>

Well, now you are missing the two-way-binding? No, we can handle the binding with just the form controls instead of needing ngModel. If you have an initial value, you can set it when you build the form:

someAmount: ['initial value', [....]]

or if you are receiving the value "later", you can use setValue (or patchValue):

this.myform.controls.someAmount.setValue("new value!")

if you need to access the value...

this.myform.get('someAmount').value

As for the validation error not showing unless you focus out from the input field, it seems it's still a bug? https://stackoverflow.com/a/39196394/7741865 which you can hack with using md-hint instead:

<md-hint *ngIf="myform.hasError('min', 'someAmount')" [ngStyle]="{'color': 'red'}"> 
   <span>amount should be not less than 10 </span> 
</md-hint>  

DEMO: https://plnkr.co/edit/ncEjsTseFLkQsHLWU2Gr?p=preview

AT82
  • 71,416
  • 24
  • 140
  • 167
  • Thanks I added this attribute as well to so the workaround behaves exactly like md-error – Hazu Aug 04 '17 at 13:53