Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to avoid duplication of code in the forms Angular 2?

Tags:

oop

angular

All my reactive forms usually include properties and methods:

  @Input()
  public form: FormGroup;

  public messages = VALIDATION_MESSAGES;

  @Output()
  public onFormSubmit: EventEmitter<any> = new EventEmitter();

  @Input()
  public formData;

  @Input()
  public controlsConfig: any;

  protected abstract fb: FormBuilder;

  isValidControl(controlName: string): boolean {
    const control = this.form.controls[controlName];
    return control.valid || control.pristine;
  }
  onSubmit(): void {
    const form = this.form;

    if(form.valid) {
      this.onFormSubmit.emit(form.value);
    }
  }

I selected them in the abstract class

export abstract class BaseReactiveForm {..}

And inherit

@Component({
  selector: 'app-login-form',
  templateUrl: './login-form.component.html',
  styleUrls: ['./login-form.component.css']
})
export class LoginFormComponent extends BaseReactiveForm implements OnInit {

  constructor(protected fb: FormBuilder) {
    super();
  }
...}

Is it true that decision?

How to do the right thing? what are the forms of practice?

like image 415
Gleb Patcia Avatar asked Jan 23 '17 15:01

Gleb Patcia


Video Answer


1 Answers

I did the same on my projects, created a base class to handle the reactive forms stuff. I think that It's ok, we should use OOP to simplify this kind of stuff. I read somewhere that they will tweak this part of the framework, because It's repetitive, verbose!

Here's my Impl:

import { FormGroup } from '@angular/forms';

export interface ValidatableFormComponent {
    formGroup: FormGroup;
    formErrors: any;
    validationMessages: any;
    onValueChanged(data?: any): void;
    buildForm(): void;
    onSubmit($event): void;
}

import { FormGroup, FormBuilder } from '@angular/forms';
import { ValidatableFormComponent } from './validatable-form.component';

export class FormBaseComponent implements ValidatableFormComponent {
  formGroup: FormGroup;
  formErrors: any;
  validationMessages: any;

  constructor(protected fb: FormBuilder) { }

  buildForm(): void {
    this.formGroup.valueChanges
      .subscribe(data => this.onValueChanged(data));
    this.onValueChanged();
  }

  onSubmit($event): void {
    $event.preventDefault();
  }

  onValueChanged(data?: any): void {
    if (!this.formGroup) {
      return;
    }

    const form = this.formGroup;
    for (const field in this.formErrors) {
      if (this.formErrors.hasOwnProperty(field)) {
        this.formErrors[field] = '';
        const control = form.get(field);

        if (control && control.dirty && !control.valid) {
          const messages = this.validationMessages[field];
          for (const key in control.errors) {
            if (control.errors.hasOwnProperty(key)) {
              this.formErrors[field] += messages[key] + ' ';
            }
          }
        }
      }
    }
  }

  isValid(): boolean {
    return this.formGroup.valid;
  }
}
like image 90
Fals Avatar answered Sep 24 '22 03:09

Fals