DEV Community

Cover image for Building scalable robusts and type safe forms with Angular

Building scalable robusts and type safe forms with Angular

Maxime on June 16, 2019

Hi there 👋! Today I'd like to share some of my experience in building (what I think are) large and complex forms with Angular. One thing to keep i...
Collapse
 
andrewtraub profile image
AndrewTraub

I'm using angular 7 and so installed version 2.7.1 but my compiler is showing all kinds of problems with it - like DataInput and NgxRootFormComponent aren't in ngx-sub-form. Will the latest version work with angular 7?

Collapse
 
maxime1992 profile image
Maxime

Hi Andrew,

Angular 7 support ended after 2.7.1 I'm afraid!

DataInput landed in v2.9.0 github.com/cloudnc/ngx-sub-form/re...

Collapse
 
andrewtraub profile image
AndrewTraub

So do you have sample code that works with 2.7.1 or do I need to upgrade to angular 8 in order to get my code working?

Thanks,

Andrew

Thread Thread
 
maxime1992 profile image
Maxime

You can clone the project:

git clone git@github.com:cloudnc/ngx-sub-form.git

and checkout the latest version working with angular 7

git checkout v2.7.1

From there you'll have the README and the whole demo project working with Angular 7.

If you want to use new features that appeared after 2.7.1 or take advantage of the latest bug fixes you'll have to upgrade to Angular 8 and then use the latest of ngx-sub-form.

Hope it makes sense.
If you can and there's no particular blocker, I'd recommend upgrading to Angular 8 anyway :)

Thread Thread
 
andrewtraub profile image
AndrewTraub

Thanks. Is there any way to add a custom validation for the entire group? Normally, I'd do so like this:

createFormGroup() {
this.myForm = this.fb.group({
mobile : new FormControl(''),
homePhone : new FormControl('')
// our custom validator
}, { validator: this.atLeastOnePhoneRequired});
}

but in the form using ngx-sub-form I'm using code like this:
protected getFormControls(): Controls {
return {
mobile : new FormControl(null),
homePhone : new FormControl(null)
};
}

Thread Thread
 
maxime1992 profile image
Maxime

Yes, there's definitely a way to do that.

Search getFormGroupControlOptions on the README :)

Collapse
 
cbleu profile image
cesar jacquet

Hi Maxime, thank you for that very nice lib and tutorial.

Just a stupid question, i have to make "checkbox-group" for a project, that work exactly like a "select" with multivalues accepted. What is the best method to do that with ngx-sub-form ?
We need that, just because my customer prefer the look of a checkbox group than a "select" dropdown on phone.
In fact i would love to have a component like "radiogroup" or "select" that directly display a checkbox group. To do that, is it better to create as a sub-form of my main form for each "checkbox-group" or create a specific "widget" just for that ?

Collapse
 
maxime1992 profile image
Maxime

Hi Cesar, thanks for the kind words.

There is no stupid question :)!
Can you please open an issue here github.com/cloudnc/ngx-sub-form/is... so that other people wondering the same thing might find it easily?

Thanks

Collapse
 
cbleu profile image
cesar jacquet

Ok, i va added the question to your github page.

Thanks

Collapse
 
mtpultz profile image
Martin Pultz

Great article, how would you handle value transformations in subforms using ControlValueAccessors so you could do conversions like cents into dollars for values as they get patched, and dollars to cents when accessing the form value. I've got an initial way of accomplishing this using two directives (toDollars and toCents) and using a mask on the dollars via Maskito, but it feels janky and requires adding the 2 directives to all currency fields.

Collapse
 
elvispdosreis profile image
Elvis P dos Reis

following the example
stackblitz.com/edit/ngx-sub-form-b...
I need to put all the controls inside a single component in the "FormArray", however I didn't understand how to access the "compartment.formControlNames.deck"

screen

Collapse
 
maxime1992 profile image
Maxime

Hi Elvis, I think all you need to do is change FormControlName for deck and size to a simple FormControl to witch you'd pass the compartment.

If you provide a minimal repro on stackblitz I may help you out

Collapse
 
m12lrpv profile image
m12lrpv

12 months on and this plugin is fantastic but i'm struggling to use it in one aspect. One to many master detail forms.

Is there a working example similar to the suggestion of adding multiple colours to your spaceship example or the Authors example mentioned in github.com/cloudnc/ngx-sub-form/is...

Collapse
 
m12lrpv profile image
m12lrpv

I later realised that you're demo app had the functionality. I've forked your simplified demo to include the FormArray functionality
stackblitz.com/edit/ngx-sub-form-b...

Collapse
 
purplenimbus profile image
Anthony Akpan

Unless I'm missing something here, how is this diffrent from the native angular form builder?

Dont quote me on this but I'm sorta sure that one can build complex forms in a child parent manner using just the form builder.

Generate the form in the root component and pass individual form groups, form arrays to the sub components

Collapse
 
maxime1992 profile image
Maxime • Edited

Hi Antony,

yes ngx-sub-forms is different than what you can do with FormBuilder.

FormBuilder is a simple helper to save you some boilerplate instead of using directly new FormGroup().

If you refer to breaking-down-the-form-into-sub-co... and breaking-down-the-form-into-sub-co..., I've explained why using a ControlValueAccessor instead of passing a FormGroup (or FormArray, FormControl, etc) is a better idea.

But ngx-sub-form is also going further than that:

  • Type safety (within .ts and .html)
  • Helpers (see what-raw-ngxsubform-endraw-has-to-...) including for example the retrieval of errors from a parent with nested ones too, that is not possible with form groups
  • Gives you methods, to have for a given form a different internal structure which is important for dealing with polymorphic data

It feels like I'm quoting myself from the article without adding much in this comment so not sure how helpful this will be to you... Let me know if you're still not convinced :). Maybe you can make a demo on stackblitz using inputs to pass a formGroup and I can fork your demo to show you the difference with ngx-sub-form 👍

Oh and I almost forgot, but using a ControlValueAccessor you let people decide whether they want to use a template form or a reactive one. So you could build a sub component with ngx-sub-form in a reactive way, and consume it as part of another form with a template syntax for example. Which is not the case when you pass a formGroup

Collapse
 
thanh_pd profile image
Thanh Phan • Edited

Thanks, I really appreciate advanced Angular posts like this. ReactiveForm is useful but I feel like working with form in Angular can be better than what we're having.

Collapse
 
maxime1992 profile image
Maxime

Thanks, I really appreciate advanced Angular posts like this

Hi Thanh! Thanks for the kind words.

I agree, feels like reactive forms could go further than what they currently do. In the meantime, let's improve them as much as we can ourselves!

Collapse
 
spock123 profile image
Lars Rye Jeppesen

Wow awesome

Collapse
 
maxime1992 profile image
Maxime

Thanks Lars! =)

Collapse
 
tashoecraft profile image
Austin Shoecraft

As someone who has endured the battle of Reactive Forms, this is looking really good. Curious to your opinions to ngrx-forms. It's not the easiest to get started, but I've really liked the integration an the functional aspect of it.

Collapse
 
maxime1992 profile image
Maxime

As someone who has endured the battle of Reactive Forms, this is looking really good

I appreciate that :)! Hopefully it might help you a bit in the future.

Curious to your opinions to ngrx-forms

I've never used it yet and don't have time to dive into their doc right now so can't make any comment about it.

Collapse
 
fredsteffen profile image
fredsteffen

Excellent article and a great solution to a tricky problem. Thanks for posting!

Collapse
 
maxime1992 profile image
Maxime

Glad you liked it, thanks for letting me know :)

Collapse
 
elvispdosreis profile image
Elvis P dos Reis

I need to interact all the elements of the FormGroup but they are all the same type in the subform
github issue

Collapse
 
mthood profile image
mthood • Edited

i'l suggest also this:

davembush.github.io/attaching-an-a...

It's not type safe solution, but really, really smart.
thank's for your great job

Collapse
 
kostyatretyak profile image
Костя Третяк • Edited

Every Subscription that returns from .subscribe() need call .unsubscribe() in the OnDestroy() method. Exceptions to this rule are provided only for HttpClient.