8
\$\begingroup\$

I am taking a first pass at Angular Forms with some colleagues and noticed an interesting design pattern implemented by a coworker where the FormControl is being extended to allow for additional properties including flags like readonly, showcancel and a few other custom properties.

The controls are then iterated over in the form template to then render each input. This is a big concern to me as we are extending the base Angular classes that could change with updates to the framework.

Here is an example of what I am talking about:

export class FormGroupModel extends FormGroup {
    readOnly: boolean;
    showCancel: boolean;
    controls: { [key: string]: FormControlModel | FormGroupModel };

    get(controlName: string): FormControlModel {
        return <FormControlModel> super.get(controlName);
    }
}

export class FormControlModel extends FormControl {
    readOnly: boolean;
    showCancel: boolean;
}

Is there anything else that we should keep in mind when using this strategy? I'm not totally certain that these classes were meant to be extended...

\$\endgroup\$
1
  • \$\begingroup\$ I'd like to see some commentary on this as I am trying to extend my Angular 9 formControls and have not had any luck. \$\endgroup\$
    – user62927
    Commented Aug 2, 2020 at 21:57

1 Answer 1

2
\$\begingroup\$
  1. Update the signature of the module to include your new properties. This will let the compiler know about your new properties and will prevent it from throwing errors in the HTML template or in the component.ts file.

    declare module '@angular/forms' {
      interface AbstractControl {
        focused: boolean;
      }
    }
    

    I added AbstractControl because that is the base class that FormControl is built on and derives its properties from.

  2. Add your new properties by extending the class, passing through (...args) for both the constructor(...args) and super(...args) calls.

    export class FormControlCustom extends FormControl {
    
      public focused: boolean = false;
    
      constructor(...args) {
        super(...args);
      }
    
    }
    
  3. Typecast your FormControl. Now all your FormControlCustom elements will have the new properties defined in the class which extends FormControl by default.

    sampleForm = new FormGroup({
        property: new FormControlCustom('', Validators.required)
    });
    

I tested this and it is working perfectly in Angular 9.

\$\endgroup\$
5
  • 5
    \$\begingroup\$ Welcome to Code Review! Can you tell us more about the improvements of this code relative to the presented code? That would make it an actual review. Now it looks more like an alternative implementation, but I'm sure you'll think of something. Thanks! \$\endgroup\$
    – Mast
    Commented Aug 4, 2020 at 16:23
  • \$\begingroup\$ @Mast, I guess my thinking was that the code provided doesn't fully document all that is needed. I am not simply providing an alternate implementation. If someone where to copy and paste the code above, without further explanation, it wouldn't work. Also the parts about constructor and super was also totally missing. I think it needs to be mentioned they are needed. \$\endgroup\$
    – user62927
    Commented Aug 4, 2020 at 17:33
  • 6
    \$\begingroup\$ @PhillipBerger I think you are missing Mast's points, Code Review is very different from Stack Overflow, we don't answer questions as much as we try to improve the original posters code. What you have presented is an alternate solution and that's not the point of code review. You might want to take a look at the help center. \$\endgroup\$
    – pacmaninbw
    Commented Aug 4, 2020 at 17:36
  • \$\begingroup\$ @pacmaninbw: Fairs points but please see my above comment. You can't extend the form control without calling the constructor() and super(). At a minimum my answer draws attention to that, so it is a code review. \$\endgroup\$
    – user62927
    Commented Aug 4, 2020 at 17:38
  • 5
    \$\begingroup\$ I feel this is lacking the "further explanation" part of "If someone where to copy and paste the code above, without further explanation, it wouldn't work." I don't really understand what this code does and how it's better than the OP's. Could you help bridge the gap between your code and the OP's through explaining why you've done what you've done? \$\endgroup\$
    – Peilonrayz
    Commented Aug 5, 2020 at 11:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.