Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I know when custom form control is marked as pristine in Angular?

Tags:

I have several custom form control components in my Angular application, which implement ControlValueAccessor interface and it works great.

However, when markAsPristine() is called on parent form, or on my custom control directly I need to update it's state: my custom control is actually have internal control and I need to call markAsPristine() on it too.

SO, how do I know when markAsPristine() is called on my control?

The ControlValueAccessor interface has no members, related to this problem, which I can implement.

like image 567
Slava Fomin II Avatar asked Jun 23 '17 22:06

Slava Fomin II


People also ask

What is pristine in form control?

"pristine" means the user hasn't changed the value since it was displayed in this form. So given a user has an autocomplete input that looks up airports nearby, when the user selects an option then we set the value of the FormControl to the selected option.

What is pristine Angular?

ng-pristine The field has not been modified yet. ng-dirty The field has been modified. ng-valid The field content is valid. ng-invalid The field content is not valid.

How do you mark all form controls as touched?

Directive To Mark Form Touched First, we target forms that have the formGroup directive. Next, we obtain a reference to the FormGroupDirective instance via dependency injection. The last thing we need to do is register the submit event and call method to mark all form fields as touched.


1 Answers

After thorough investigation I've found out that this functionality is not specifically provided by Angular. I've posted an issue in the official repository regarding this and it's gained feature request status. I hope it will be implemented in near future.


Until then, here's two possible workarounds:

Monkey-patching the markAsPristine()

@Component({
  selector: 'my-custom-form-component',
  templateUrl: './custom-form-component.html',
  providers: [{
    provide: NG_VALUE_ACCESSOR,
    useExisting: MyCustomFormComponent,
    multi: true
  }]
})
export class MyCustomFormComponent implements ControlValueAccessor, OnInit {

  private control: AbstractControl;


  ngOnInit() {
    const origFunc = this.control.markAsPristine;
    this.control.markAsPristine = function() {
      origFunc.apply(this, arguments);
      console.log('Marked as pristine!');
    }
  }

}

Watching for changes with ngDoCheck

Be advised, that this solution could be less performant, but it gives you better flexibility, because you can monitor when pristine state is changed. In the solution above, you will be notified only when markAsPristine() is called.

@Component({
  selector: 'my-custom-form-component',
  templateUrl: './custom-form-component.html',
  providers: [{
    provide: NG_VALUE_ACCESSOR,
    useExisting: MyCustomFormComponent,
    multi: true
  }]
})
export class MyCustomFormComponent implements ControlValueAccessor, DoCheck {

  private control: AbstractControl;

  private pristine = true;


  ngDoCheck(): void {
    if (this.pristine !== this.control.pristine) {
      this.pristine = this.control.pristine;
      if (this.pristine) {
        console.log('Marked as pristine!');
      }
    }
  }

}

And if you need to access the FormControl instance from your component, please see this question: Get access to FormControl from the custom form component in Angular.

like image 144
Slava Fomin II Avatar answered Oct 05 '22 01:10

Slava Fomin II