Search code examples
angularangular-formsangular-reactive-forms

Why are FormGroup controls null after formGroup.reset()?


I have this reactive form that I'm setting up with:

const v = Validators;

this.entryForm = this.formBuilder.group({

  firstName: ['', [v.minLength(2), v.required]],
  lastName: ['', [v.minLength(2), v.required]],
  email: ['', [v.email, v.required]],
  instagram: ['', [v.minLength(2), v.required]],
  company: [''],
  title: [''],
  agree: [false, v.requiredTrue],

});

But after I call this.entryForm.reset(), like:

this.entryForm.reset();

...the form controls of entryForm are null, causing errors. Even if I try re-instantiating the FormGroup, I still see null form controls. What the heck am I doing wrong?

Here is the complete component TypeScript:

@Component({
  selector: 's2es-enter-page',
  templateUrl: './enter-page.component.html',
  styleUrls: [
    './enter-page.component.sass',
  ]
})
export class EnterPageComponent extends AbstractPageComponent implements OnInit {

  entryForm: FormGroup;
  inited = false;

  constructor(
    private readonly pageService: PageService,
    private readonly http: HttpClient,
    private readonly formBuilder: FormBuilder,
  ) {
    super(pageService);

    this.entryForm = new FormGroup({
      first: new FormControl(),
    });

    (window as any).localJsonpCallback = () => {
      this.entryForm.reset();
    };
  }

  onSubmit() {
    const url = 'https://script.google.com/macros/s/AKfycbyRrxv8Ri-GRpuXqWXo2inCPzmAE8mG6Q8oQIGPmUeMaGbD5jCn/exec?';
    const q: string[] = [];
    const company = this.entryForm.get('company').value + ',' + this.entryForm.get('title').value;
    const name = this.entryForm.get('firstName').value + ',' + this.entryForm.get('lastName').value;

    q.push('name=' + name);
    q.push('email=' + this.entryForm.get('email').value);
    q.push('instagram=' + this.entryForm.get('instagram').value);
    if (company.length > 1) { q.push('company=' + company); }
    q.push('prefix=localJsonpCallback');

    const uri = url + q.join('&');
    this.http.jsonp(uri, 'JSONP_CALLBACK').subscribe((val) => {
      console.log(val);
    });
  }

  /**
   * Since this is not supported on MS browsers.
   */
  placeholderShown(id: string): boolean {
    if (this.inited) {
      if (this.entryForm.get(id).value !== null) {
        return !this.entryForm.get(id).value.length;
      } else {
        // I don't know why this is null.
        // throw new Error(id);
        // return false;
      }
    }
  }

  setupForm() {

    const v = Validators;

    this.entryForm = this.formBuilder.group({

      firstName: ['', [v.minLength(2), v.required]],
      lastName: ['', [v.minLength(2), v.required]],
      email: ['', [v.email, v.required]],
      instagram: ['', [v.minLength(2), v.required]],
      company: [''],
      title: [''],
      agree: [false, v.requiredTrue],

    });
  }

  /**
   *
   */
  ngOnInit() {

    super.ngOnInit();

    this.setupForm();

    this.inited = true;

  }

}

Solution

  • Since Angular 14, you can set nonNullable in the FormControlOptions of the FormControl constructor if you want to reset it to the initial values.

    const fish = new FormControl('finn', {nonNullable: true});