{"id":747,"date":"2018-03-15T12:11:00","date_gmt":"2018-03-15T12:11:00","guid":{"rendered":"https:\/\/staging.infragistics.com\/blogs\/?p=747"},"modified":"2025-02-18T13:15:16","modified_gmt":"2025-02-18T13:15:16","slug":"conditional-validation-in-angular-reactive-forms","status":"publish","type":"post","link":"https:\/\/www.infragistics.com\/blogs\/conditional-validation-in-angular-reactive-forms","title":{"rendered":"Conditional Validation on valueChanges Method in Angular Reactive Forms"},"content":{"rendered":"\n<p>In this blog post, we will learn to use Angular Reactive Forms value change detection and enable conditional validation on basis of that with the help of the best and most complete <a href=\"\/products\/ignite-ui-angular\">Angular Component Libraries<\/a> out there &#8211; <a href=\"\/products\/ignite-ui\">Ignite UI<\/a>.<\/p>\n\n\n\n<p>Learn <a href=\"\/blogs\/how-to-create-your-first-angular-reactive-form\/\">How to Create Your First Angular Reactive Form<\/a> here.<\/p>\n\n\n\n<p>Let us say you have a Reactive Form created using FormBuilder class as shown below:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">ngOnInit() {\n    this.loginForm = this.fb.group({\n      email: [null, Validators.required],\n      password: [null, [Validators.required, Validators.maxLength(8)]],\n      phonenumber: [null]\n    });\n\n  }<\/pre>\n\n\n\n<p>You have created loginForm, which has three controls: email, password, and phonenumber. Here, you are using FormBuilder to create a reactive form. On the component template, you can attach loginForm as shown in the code listing below. Using property binding, the formGroup property of the HTML form element is set to loginForm and the formControlName value of these controls are set to the individual FormControl property of FormBuilder.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">&lt;form (ngSubmit)='loginUser()' [formGroup]='loginForm' novalidate class=\"form\">\n     &lt;input formControlName='email' type=\"text\" class=\"form-control\" placeholder=\"Enter Email\" \/>\n     &lt;div class=\"alert  alert-danger\" *ngIf=\"loginForm.get('email').hasError('required') &amp;&amp; loginForm.get('email').touched\">\n         Email is required\n     &lt;\/div>\n     &lt;input formControlName='password' type=\"password\" class=\"form-control\" placeholder=\"Enter Password\" \/>\n     &lt;input formControlName='phonenumber' type=\"text\" class=\"form-control\" placeholder=\"Enter Phone Number\" \/>\n     &lt;div class=\"alert  alert-danger\" *ngIf=\"loginForm.get('phonenumber').hasError('required') &amp;&amp; loginForm.get('phonenumber').touched\">\n         Phone Number is required\n     &lt;\/div>\n     &lt;br \/>\n     &lt;button [disabled]='loginForm.invalid' class=\"btn btn-default\">Login&lt;\/button>\n &lt;\/form><\/pre>\n\n\n\n<p>We have also put error messages for email and phone number fields. Besides, that submit button would only be enabled when the form is valid. &nbsp;Form submit is handled as shown in the listing below:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">loginUser() {\n    console.log(this.loginForm.status);\n    console.log(this.loginForm.value);\n}<\/pre>\n\n\n\n<p>If the form is valid in browser console, you will get the output as below:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"http:\/\/static.infragistics.com\/marketing\/Blogs\/Migration\/00\/00\/00\/09\/43\/4645.pic1.png\" alt=\" \"\/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>In addition, if there is an error, submit button would be disabled and an error message will be shown as below:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"http:\/\/static.infragistics.com\/marketing\/Blogs\/Migration\/00\/00\/00\/09\/43\/7142.pic2.png\" alt=\" \"\/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>You can learn to create <a href=\"\/blogs\/how-to-create-custom-validators-for-angular-reactive-forms\/\">Custom Validators for Angular Reactive Forms<\/a> here.<\/p>\n\n\n\n<p>Now assume a scenario that you have a radio button to send a notification. The user should able to select the send notification option, and on basis of that, certain FormControl will have some validation.<\/p>\n\n\n\n<p>Consider the form below,<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"http:\/\/static.infragistics.com\/marketing\/Blogs\/Migration\/00\/00\/00\/09\/43\/1856.pic3.png\" alt=\" \"\/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>We have added a Send Notification option. If the user selects Phone to send notification then Phone Number field should be required, otherwise, it should not be. To achieve this we need to perform following tasks,<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Listening to changes<\/li>\n\n\n\n<li>Put conditional validation<\/li>\n<\/ol>\n\n\n\n<p>&nbsp;To start with, let us modify our form to handle the notification. So now form has a notification FormControl with the default value set to null as shown in the listing below :<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">this.loginForm = this.fb.group({\n    email: [null, Validators.required],\n    password: [null, [Validators.required, Validators.maxLength(8)]],\n    phonenumber: [null],\n    notification: ['email']\n});<\/pre>\n\n\n\n<p>On the Reactive form template, we will add radio button group to handle Send Notification option.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">&lt;form (ngSubmit)='loginUser()' [formGroup]='loginForm' novalidate class=\"form\">\n    &lt;input formControlName='email' type=\"text\" class=\"form-control\" placeholder=\"Enter Email\" \/>\n    &lt;div class=\"alert  alert-danger\" *ngIf=\"loginForm.get('email').hasError('required') &amp;&amp; loginForm.get('email').touched\">\n        Email is required\n    &lt;\/div>\n    &lt;input formControlName='password' type=\"password\" class=\"form-control\" placeholder=\"Enter Password\" \/>\n    &lt;input formControlName='phonenumber' type=\"text\" class=\"form-control\" placeholder=\"Enter Phone Number\" \/>\n    &lt;div class=\"alert  alert-danger\" *ngIf=\"loginForm.get('phonenumber').hasError('required') &amp;&amp; loginForm.get('phonenumber').touched\">\n        Phone Number is required\n    &lt;\/div>\n    &lt;br \/>\n    &lt;label class='control-label'>Send Notification&lt;\/label>\n    &lt;br \/>\n    &lt;label class=\"radio-inline\">\n        &lt;input type=\"radio\" value=\"email\" formControlName=\"notification\">Email\n    &lt;\/label>\n    &lt;label class=\"radio-inline\">\n        &lt;input type=\"radio\" value=\"phone\" formControlName=\"notification\">Phone\n    &lt;\/label>\n \n    &lt;br \/>\n    &lt;button [disabled]='loginForm.invalid' class=\"btn btn-default\">Login&lt;\/button>\n&lt;\/form><\/pre>\n\n\n\n<p>At this point form, looks like below:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"http:\/\/static.infragistics.com\/marketing\/Blogs\/Migration\/00\/00\/00\/09\/43\/1856.pic4.png\" alt=\" \"\/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"subscribe-to-valuechanges\"><b>Subscribe to valueChanges<\/b><\/h2>\n\n\n\n<p>In Reactive forms both FormControls and FormGroups has a <strong>valueChanges<\/strong> method. It returns an observable type, so you can subscribe to it, to work with real-time value changing of FormControls or FormGroups.<\/p>\n\n\n\n<p>In our example, we need to subscribe to valueChanges of notification FormControl. This can be done as below:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">formControlValueChanged() {\n    this.loginForm.get('notification').valueChanges.subscribe(\n        (mode: string) => {\n            console.log(mode);\n        });\n}<\/pre>\n\n\n\n<p>We need to call this an OnInit lifecycle hook a shown below:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">ngOnInit() {\n    this.loginForm = this.fb.group({\n        email: [null, Validators.required],\n        password: [null, [Validators.required, Validators.maxLength(8)]],\n        phonenumber: [null],\n        notification: ['email']\n    });\n\n    this.formControlValueChanged();\n\n}<\/pre>\n\n\n\n<p>Now when you change the selection for notification on the form in the browser console you can see, you have most recent value.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"http:\/\/static.infragistics.com\/marketing\/Blogs\/Migration\/00\/00\/00\/09\/43\/0218.pic5.png\" alt=\" Now when you change the selection for notification on the form in the browser console you can see, you have most recent value.\" title=\"Now when you change the selection for notification on the form in the browser console you can see, you have most recent value.\"\/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>Keep in mind that, we are not handling any event on the radio button to get the latest value. Angular has a valueChanges method which returns recent value as observable on the FormControl and FormGroup, and we are subscribed to that for recent value on notification FormControl.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"conditional-validation\"><b>Conditional Validation<\/b><\/h2>\n\n\n\n<p>Our requirement is that when notification is set to phone then phonenumber FormControl should be required field and if it is set to email then phonenumber FormControl should not have any validation.<\/p>\n\n\n\n<p>Let us modify formControlValueChnaged() function as shown in the next listing to enable conditional validation on phonenumber FormControl.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">formControlValueChanged() {\n    \n    const phoneControl = this.loginForm.get('phonenumber');\n    this.loginForm.get('notification').valueChanges.subscribe(\n        (mode: string) => {\n            console.log(mode);\n            if (mode === 'phone') {\n                phoneControl.setValidators([Validators.required]);\n            }\n            else if (mode === 'email') {\n                phoneControl.clearValidators();\n            }\n            phoneControl.updateValueAndValidity();\n        });\n\n}<\/pre>\n\n\n\n<p>&nbsp;<\/p>\n\n\n\n<p>There are a lot of codes above, so talk through line by line. &nbsp;<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Using get method of FormBuilder getting an instance of phone number FormControl<\/li>\n\n\n\n<li>Subscribing to the valueChanges method on notification FormControl<\/li>\n\n\n\n<li>Checking the current value of notification FormControl<\/li>\n\n\n\n<li>If the current value is phone, using setValidators method of FormControl to set required validator on phonenumber control<\/li>\n\n\n\n<li>If the current value is email, using clearValidators method of FormControl to clear all validation on phonenumber control<\/li>\n\n\n\n<li>In last calling updateValueAndValidity method to update validation rules of phonecontrol<\/li>\n<\/ol>\n\n\n\n<p>Run the application and you will see that as you change notification value, validation of phonenumber is getting changed,<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"http:\/\/static.infragistics.com\/marketing\/Blogs\/Migration\/00\/00\/00\/09\/43\/0218.pic6.png\" alt=\" Run the application and you will see that as you change notification value\" title=\"Run the application and you will see that as you change notification value\"\/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>By using the power of Angular Reactive Form\u2019s valueChanges method, you can achieve conditional validations and many other functionalities such as reacting to changes in the underlying data model of the reactive form.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Like this post?<\/h4>\n\n\n\n<p>If you like this post, please share it. In addition, if you haven\u2019t checked out our library yet,&nbsp;be sure to do so! It is the most complete toolbox with&nbsp;Material-based UI components, the fastest <a href=\"\/products\/ignite-ui-angular\/angular\/components\/grid\/grid\">Angular data grid<\/a> on the market, and 60+ high-performance charts!<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">&nbsp;<\/h4>\n\n\n\n<figure class=\"wp-block-image\"><a href=\"\/products\/ignite-ui-angular\/download\"><img decoding=\"async\" src=\"https:\/\/static.infragistics.com\/marketing\/Blog-in-content-ads\/Ignite-UI-Angular\/ignite-ui-angular-you-get-ad.gif\" alt=\"Ignite UI for Angular benefits\"\/><\/a><\/figure>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Do you know how to use Angular Reactive Forms value change detection? This blog post will show you the ways.<\/p>\n","protected":false},"author":65,"featured_media":1107,"comment_status":"publish","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[17],"tags":[],"class_list":["post-747","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-how-to"],"_links":{"self":[{"href":"https:\/\/www.infragistics.com\/blogs\/wp-json\/wp\/v2\/posts\/747","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.infragistics.com\/blogs\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.infragistics.com\/blogs\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.infragistics.com\/blogs\/wp-json\/wp\/v2\/users\/65"}],"replies":[{"embeddable":true,"href":"https:\/\/www.infragistics.com\/blogs\/wp-json\/wp\/v2\/comments?post=747"}],"version-history":[{"count":4,"href":"https:\/\/www.infragistics.com\/blogs\/wp-json\/wp\/v2\/posts\/747\/revisions"}],"predecessor-version":[{"id":1868,"href":"https:\/\/www.infragistics.com\/blogs\/wp-json\/wp\/v2\/posts\/747\/revisions\/1868"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.infragistics.com\/blogs\/wp-json\/wp\/v2\/media\/1107"}],"wp:attachment":[{"href":"https:\/\/www.infragistics.com\/blogs\/wp-json\/wp\/v2\/media?parent=747"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.infragistics.com\/blogs\/wp-json\/wp\/v2\/categories?post=747"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.infragistics.com\/blogs\/wp-json\/wp\/v2\/tags?post=747"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}