Angular2 Custom Component - mark as pristine and untouched

The workaround with the active flag does the job but I also found another way.

On the parent form, I can access my custom child component as ViewChild.

i.e in the parent form:

@ViewChild(CustomChildComponent) child1: CustomChildComponent;

Then when I save in the parent form, call that child directly.

save(myForm: NgForm) {

   // clear anything at the parent form level
   myForm.form.markAsPristine();
   myForm.form.markAsUntouched();

   // tell the custom component to do the same
   this.child1.markAsPristineAndUntouched();
}

Where in CustomChildComponent I've defined ..

// get the input controls in the the child that we want to clear 
@ViewChild('surname') surnameField: NgModel;

markAsPristineAndUntouched() { 

   this.surnameField.control.markAsPristine();
   this.surnameField.control.markAsUntouched();
   // .. clear other controls .. 
}

Try to add controls['nameOfControl'] like this

 myForm.form.controls['nameOfControl'].markAsPristine();

The code above will only work for form controls.

THe following seems to be a good work around:

  active = true;
  newModel() {
    this.model = new yourModel(2, '',true, '');
    this.active = false;
    setTimeout(() => this.active = true, 0);
  }

Reset the form with a new Model AND to restore the 'pristine' class state. by toggling the 'active' flag will cause the form to be removed/re-added in a tick via NgIf. Yes it is a small work around until they can can fix :)

hope that helps


markAsPristine() can affect the control itself, and possibly all its direct ancestor controls (i.e. parents, grandparents, great grandparents)

markAsPristine() takes an opts argument; markAsPristine(opts: { onlySelf?: boolean; } = {}). When the onlySelf value is false (which is the default value )), the control and all its direct ancestors are marked as pristine. If onlySelf is true; only the control itself is marked as pristine.

In my case, I wanted to mark all descendant controls (i.e. child, grandchild, etc) as pristine/untouched. I can do this using FormGroup.reset() ; reset() has the ability to affect descendants:

Resets the FormGroup, marks all descendants are marked pristine and untouched, and the value of all descendants to null.

So with the OP's code I could reset the form, using the values it already has:

myForm.form.reset(myForm.form.getRawValue(), {emitEvent: false})

Note how I avoid certain side effects:

  • I use the form's current values, so I don't change current values.
  • I use getRawValue(), instead of value, to get the value of disabled controls.
  • I don't emitEvent; which means no valueChanges will be triggered.