119

I have some simple angular 2 component with template. How to clear form and all fields after submit?. I can't reload page. After set data with date.setValue('') field is stil touched.

import {Component} from 'angular2/core';
import {FORM_DIRECTIVES, FormBuilder, ControlGroup, Validators, Control} from 'angular2/common';

@Component({
    selector: 'loading-form',
    templateUrl: 'app/loadings/loading-form.component.html',
    directives: [FORM_DIRECTIVES]
})

export class LoadingFormComponent {
    private form:ControlGroup;
    private date:Control;
    private capacity:Control;

    constructor(private _loadingsService:LoadingsService, fb:FormBuilder) {
        this.date = new Control('', Validators.required);
        this.capacity = new Control('', Validators.required);
        this.form = fb.group({
            'date': this.date,
            'capacity': this.capacity
        });
    }

    onSubmit(value:any):void {
        //send some data to backend
    }
}

loading-form.component.html

<div class="card card-block">
    <h3 class="card-title">Loading form</h3>

    <form (ngSubmit)="onSubmit(form.value)" [ngFormModel]="form">
        <fieldset class="form-group" [class.has-danger]="!date.valid && date.touched">
            <label class="form-control-label" for="dateInput">Date</label>
            <input type="text" class="form-control form-control-danger form-control-success" id="dateInput"
                   min="0" placeholder="Enter loading date"
                   [ngFormControl]="form.controls['date']">
        </fieldset>
        <fieldset class="form-group" [class.has-danger]="!capacity.valid && capacity.touched">
            <label class="form-control-label" for="capacityInput">Capacity</label>
            <input type="number" class="form-control form-control-danger form-control-success" id="capacityInput"
                   placeholder="Enter capacity"
                   [ngFormControl]="form.controls['capacity']">
        </fieldset>
        <button type="submit" class="btn btn-primary" [disabled]="!form.valid">Submit
        </button>
    </form>
</div>
masel.popowo
  • 1,383
  • 2
  • 8
  • 11

15 Answers15

186

See also https://angular.io/docs/ts/latest/guide/reactive-forms.html (section "reset the form flags")

>=RC.6

In RC.6 it should be supported to update the form model. Creating a new form group and assigning to myForm

[formGroup]="myForm"

will also be supported (https://github.com/angular/angular/pull/11051#issuecomment-243483654)

>=RC.5

form.reset();

In the new forms module (>= RC.5) NgForm has a reset() method and also supports a forms reset event. https://github.com/angular/angular/blob/6fd5bc075d70879c487c0188f6cd5b148e72a4dd/modules/%40angular/forms/src/directives/ng_form.ts#L179

<=RC.3

This will work:

onSubmit(value:any):void {
  //send some data to backend
  for(var name in form.controls) {
    (<Control>form.controls[name]).updateValue('');
    /*(<FormControl>form.controls[name]).updateValue('');*/ this should work in RC4 if `Control` is not working, working same in my case
    form.controls[name].setErrors(null);
  }
}

See also

Günter Zöchbauer
  • 623,577
  • 216
  • 2,003
  • 1,567
  • 2
    @masel.popowo Yes, If you want `pristine`, ..., then rebuilding the form is currently the only option. – Günter Zöchbauer Jan 12 '16 at 11:36
  • @günter-zöchbauer how do you rebuild the form? – SimonHawesome Mar 02 '16 at 16:18
  • 2
    I haven't tried it myself yet but I guess you just drop the controlgroup and create a new one. Move the code to a function so you can call it repeatedly if necessary. – Günter Zöchbauer Mar 02 '16 at 16:20
  • +1 for setErrors(). By the way a mistake I document here a mistake I made in case somebody else does sth similar: in case you use a placeholder e.g. 'foo' do not call control.updateValue('foo') but instead call control.setValue(null) – Mike Argyriou Mar 28 '16 at 17:38
  • I don't know about a `setValue()` method on control. Only `updateValue()` https://github.com/angular/angular/blob/master/modules/angular2/src/common/forms/model.ts#L294 – Günter Zöchbauer Mar 28 '16 at 17:41
  • This solution makes `form.value` to true which should not be the behavior of the form having empty inputs. – Eesa Apr 05 '16 at 10:29
  • @essaji it's only a workaround until Angular provides something out-of-the-box. I don't know how to improve. Another workaround is to recreate the form. – Günter Zöchbauer Apr 05 '16 at 10:32
  • you can always call .updateValueAndValidity() on each control when you submit to make sure any validation fires after youv've reset – Raj Apr 14 '16 at 12:49
  • @GünterZöchbauer When taking advantage of observables, if one rebuilds the form completely, I guess all her/his `myForm.valueChanges` observable subscriptions must be recreated as well, plus the old subscriptions must be unsubscribed ... right? – superjos May 23 '16 at 11:14
  • You might want to have a method to which you can send your model that that be instantiated or null, and if null use empty string or value from the model. After you submit your form call this method with null parameter to rebuild the form. – Huske Aug 30 '16 at 19:43
  • From where I import Control on <=RC.3? – Victor Carvalho Sep 10 '16 at 21:45
  • Don't remember. Depends on what forms module you use `@angular/forms`, `@angular/forms-deprecated`. – Günter Zöchbauer Sep 10 '16 at 21:46
  • I'm using @angular/forms – Victor Carvalho Sep 10 '16 at 21:47
  • You might be interested in this answer as well https://stackoverflow.com/questions/48216330/angular-5-formgroup-reset-doesnt-reset-validators – Mauricio Gracia Gutierrez Jun 12 '19 at 01:07
  • Notice that .reset() will set all fields' values to `null`, NOT the default values: https://stackoverflow.com/questions/54588918/angular-form-reset-value-and-set-all-its-initial-value-rather-than-null. So if you're using a property (e.g. get the length of a field to show a char counter) it will throw an error. You have to map all values to `''` or rebuild the whole form. – GusSL Apr 09 '21 at 13:45
40

As of Angular2 RC5, myFormGroup.reset() seems to do the trick.

ebhh2001
  • 2,034
  • 4
  • 18
  • 27
14

Here's how I do it Angular 8:

Get a local reference of your form:

<form name="myForm" #myForm="ngForm"></form>
@ViewChild('myForm', {static: false}) myForm: NgForm;

And whenever you need to reset the form, call resetForm method:

this.myForm.resetForm();

You will need FormsModule from @angular/forms for it to work. Be sure to add it to your module imports.

Sinandro
  • 2,426
  • 3
  • 21
  • 36
  • 1
    `@ViewChild` in Angular 8 needs 2 arguments. `@ViewChild('myForm', {static: false}) myForm: NgForm;` – Tanzeel Sep 19 '19 at 06:20
13

To reset your form after submitting, you can just simply invoke this.form.reset(). By calling reset() it will:

  1. Mark the control and child controls as pristine.
  2. Mark the control and child controls as untouched.
  3. Set the value of control and child controls to custom value or null.
  4. Update value/validity/errors of affected parties.

Please find this pull request for a detailed answer. FYI, this PR has already been merged to 2.0.0.

Hopefully this can be helpful and let me know if you have any other questions in regards to Angular2 Forms.

JayKan
  • 3,966
  • 2
  • 20
  • 21
13

Make a Call clearForm(); in your .ts file

Try like below example code snippet to clear your form data.

clearForm() {

this.addContactForm.reset({
      'first_name': '',
      'last_name': '',
      'mobile': '',
      'address': '',
      'city': '',
      'state': '',
      'country': '',
       'zip': ''
     });
}
xsami
  • 1,312
  • 16
  • 31
mkumar0304
  • 637
  • 7
  • 8
13

Here is how I do it in Angular 7.3

// you can put this method in a module and reuse it as needed
resetForm(form: FormGroup) {

    form.reset();

    Object.keys(form.controls).forEach(key => {
      form.get(key).setErrors(null) ;
    });
}

There was no need to call form.clearValidators()

Mauricio Gracia Gutierrez
  • 10,288
  • 6
  • 68
  • 99
9
import {Component} from '@angular/core';
import {NgForm} from '@angular/forms';
@Component({
    selector: 'example-app',
    template: '<form #f="ngForm" (ngSubmit)="onSubmit(f)" novalidate>
        <input name="first" ngModel required #first="ngModel">
        <input name="last" ngModel>
        <button>Submit</button>
    </form>
    <p>First name value: {{ first.value }}</p>
    <p>First name valid: {{ first.valid }}</p>
    <p>Form value: {{ f.value | json }}</p>
    <p>Form valid: {{ f.valid }}</p>',
})
export class SimpleFormComp {
    onSubmit(f: NgForm) {

        // some stuff

        f.resetForm();
    }
}
Rahul Tiwari
  • 269
  • 2
  • 6
6

To angular version 4, you can use this:

this.heroForm.reset();

But, you could need a initial value like:

ngOnChanges() {
 this.heroForm.reset({
  name: this.hero.name, //Or '' to empty initial value. 
  address: this.hero.addresses[0] || new Address()
 });
}

It is important to resolve null problem in your object reference.

reference link, Search for "reset the form flags".

Lucas Selliach
  • 189
  • 1
  • 3
  • 10
6

this.myForm.reset();

This is all enough...You can get the desired output

Manikanta Sai
  • 71
  • 1
  • 2
3

There is a new discussion about this (https://github.com/angular/angular/issues/4933). So far there is only some hacks that allows to clear the form, like recreating the whole form after submitting: https://embed.plnkr.co/kMPjjJ1TWuYGVNlnQXrU/

wawka
  • 4,828
  • 3
  • 28
  • 22
  • 1
    And finally we have a method to do it in the right way: https://github.com/angular/angular/pull/9974 – wawka Sep 10 '16 at 09:47
3

To reset the complete form upon submission, you can use reset() in Angular. The below example is implemented in Angular 8. Below is a Subscribe form where we are taking email as an input.

<form class="form" id="subscribe-form" data-response-message-animation="slide-in-left" #subscribeForm="ngForm"
(ngSubmit)="subscribe(subscribeForm.value); subscribeForm.reset()">
<div class="input-group">
   <input type="email" name="email" id="sub_email" class="form-control rounded-circle-left"
      placeholder="Enter your email" required ngModel #email="ngModel" email>
   <div class="input-group-append">
      <button class="btn btn-rounded btn-dark" type="submit" id="register"
         [disabled]="!subscribeForm.valid">Register</button>
   </div>
</div>
</form>

Refer official doc: https://angular.io/guide/forms#show-and-hide-validation-error-messages.

1

I found another solution. It's a bit hacky but its widely available in angular2 world.

Since *ngIf directive removes the form and recreates it, one can simply add an *ngIf to the form and bind it to some sort of formSuccessfullySentvariable. => This will recreate the form and therefore reset the input control statuses.

Of course, you have to clear the model variables also. I found it convenient to have a specific model class for my form fields. This way i can reset all fields as simple as creating a new instance of this model class. :)

Benjamin Jesuiter
  • 1,122
  • 1
  • 13
  • 24
  • Addition: I'm using AngularDart, which doesn't have such a reset-method yet. Or at least I didn't discover it right now. :D – Benjamin Jesuiter Aug 30 '16 at 19:40
  • With RC.6 just re-initializing the forms model will do. If you move creating the forms model to a method, calling this method will reset the form. – Günter Zöchbauer Aug 30 '16 at 19:47
  • @GünterZöchbauer Oh great! I can't wait to have this feature in Angular2 for Dart too! :) Because my approach as a problem: I have a list of all input elements in my form. I get these via dart-native `querySelectorAll` in `ngAfterViewInit`. I use this list to focus the next input element on keydown.enter, instead of submitting the form. This list breaks when using ngIf to reinitialize the form. :( – Benjamin Jesuiter Aug 30 '16 at 20:59
  • OK, I fixed the problem. I can re-query the InputElement instances when i reset my form model. – Benjamin Jesuiter Aug 30 '16 at 21:05
0

Hm, now (23 Jan 2017 with angular 2.4.3) I made it work like this:

newHero() {
    return this.model = new Hero(42, 'APPLIED VALUE', '');
}
<button type="button" class="btn btn-default" (click)="heroForm.resetForm(newHero())">New Hero</button>
Adrian
  • 3,321
  • 2
  • 29
  • 46
0

Below code works for me in Angular 4

import { FormBuilder, FormGroup, Validators } from '@angular/forms';
export class RegisterComponent implements OnInit {
 registerForm: FormGroup; 

 constructor(private formBuilder: FormBuilder) { }   

 ngOnInit() {
    this.registerForm = this.formBuilder.group({
      empname: [''],
      empemail: ['']
    });
 }

 onRegister(){
    //sending data to server using http request
    this.registerForm.reset()
 }

}
Thavaprakash Swaminathan
  • 6,226
  • 2
  • 30
  • 31
-3
resetForm(){
    ObjectName = {};
}
Shivendra
  • 1
  • 1
  • Although this code might answer the question, you should add an explanation stating why/how it solves the problem. – BDL Jun 30 '17 at 12:31
  • it doesn't set the 'touched', 'pristine', etc... classes back to their original values. – Pac0 Nov 07 '17 at 13:36
  • @Shivendra This may work particularly for your problem but its not generic. You're making your `object` empty and not the `form`. – Tanzeel Sep 19 '19 at 06:22