1
\$\begingroup\$

I'm working with the ReactiveForms in Angular5 and trying to find a good way to do this.

So, in my use case, I have a FormGroup inside my example.component.ts and when I need to add some FormControl I have to do this:

ngOnInit() {
  this.form = new FormGroup({
    'myCompany': new FormControl(this.company, Validators.required),
    'myId': new FormControl(),
    'myDate': new FormControl(new Date().toISOString(), Validators.required),
    'mySotck': new FormControl('', Validators.required),
    'myItemsStock': new FormControl([], Validators.required)
  });

//[...] more codes

Well, so far everything is working well, not a big deal. But my example.component.ts has a little more fields and some of these fields have a special behavior, something like that:

ngOnInit() {

  // [...] more codes

  this.form.get('operation').valueChanges.subscribe(value => {

    if (!isNullOrUndefined(value)) {
       const operacao: MyModel = value;

      if (operacao.something) {
        this.limitDate = new Date();
      }

      if (!operacao.something) {

        this.service.search(this.company).subscribe(response => {
          const dateOffset = (24 * 60 * 60 * 1000) * response.days

          this.limitDate = new Date(new Date().getTime() - dateOffset);
        });
      }
    }

  });

  // [...] more codes

'cause this my component is getting a lot of lines code, more 400 lines. And I feel that it will be very hard to read, to understand and to maintenance.

To solve this problem I thought about creating a new class, extend the FormGroup and then set my FormControls, Validations, and behavior inside of this new class:

export class CustomFormGroup extends FormGroup {

  constructor() {
    super({
      'myCompany': new FormControl(this.company, Validators.required),
      'myId': new FormControl(),
      'myDate': new FormControl(new Date().toISOString(), Validators.required),
      'mySotck': new FormControl('', Validators.required),
      'myItemsStock': new FormControl([], Validators.required)
    });
  }

  registerListeners() {
    this.get('operation').valueChanges.subscribe(value => {

      if (!isNullOrUndefined(value)) {
        const operacao: MyModel = value;

        if (operacao.something) {
          this.limitDate = new Date();
        }

        if (!operacao.something) {

          this.service.search(this.company).subscribe(response => {
            const dateOffset = (24 * 60 * 60 * 1000) * response.days

            this.limitDate = new Date(new Date().getTime() - dateOffset);
          });
        }
      }
    }
  }

My intention with that is to reduce the complexity of my component and make it more cleary to read and understand. And split the responsibility of managing the form to another class, so when I need to use the form, I can use it this way:

// example.component.ts
this.form = new CustomFormGroup();

With this approach, I don't need to have any form's behavior in my component, once it's contained by my custom FormGroup. My question is whether this is the best way to separate concerns, and what would be better for doing that.

I'll be very glad if you give me some idea, share your experience or feedback about this approach. Feel entirely free to comment on this question.

I'm sorry if what I wrote was hard to understand, English is not my primary language and I am trying to improve that every day.

\$\endgroup\$
  • \$\begingroup\$ This code excerpt looks a bit sketchy. What is this.get('operation')? What does MyModel look like? \$\endgroup\$ – 200_success Mar 2 '18 at 18:15
  • \$\begingroup\$ MyModel is just an interface to set some types, nothing special. And this.get('operation') is the same this.form.get('operation') in the first case I'm accessing my own CustomFormGroup, in the next, I'm accessing by my component scope. \$\endgroup\$ – Ziru Zanrgeiff Mar 2 '18 at 18:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.