Notice: Function _load_textdomain_just_in_time was called incorrectly. Translation loading for the acf domain was triggered too early. This is usually an indicator for some code in the plugin or theme running too early. Translations should be loaded at the init action or later. Please see Debugging in WordPress for more information. (This message was added in version 6.7.0.) in /data/6/a/6a361ea2-86f7-4842-bcc4-d9b941aa9bc3/studioecht.com/sub/ableneo/wp-includes/functions.php on line 6170

Deprecated: Creation of dynamic property ACF::$fields is deprecated in /data/6/a/6a361ea2-86f7-4842-bcc4-d9b941aa9bc3/studioecht.com/sub/ableneo/wp-content/plugins/advanced-custom-fields-pro/includes/fields.php on line 138

Deprecated: Creation of dynamic property acf_loop::$loops is deprecated in /data/6/a/6a361ea2-86f7-4842-bcc4-d9b941aa9bc3/studioecht.com/sub/ableneo/wp-content/plugins/advanced-custom-fields-pro/includes/loop.php on line 28

Deprecated: Creation of dynamic property ACF::$loop is deprecated in /data/6/a/6a361ea2-86f7-4842-bcc4-d9b941aa9bc3/studioecht.com/sub/ableneo/wp-content/plugins/advanced-custom-fields-pro/includes/loop.php on line 269

Deprecated: Creation of dynamic property ACF::$revisions is deprecated in /data/6/a/6a361ea2-86f7-4842-bcc4-d9b941aa9bc3/studioecht.com/sub/ableneo/wp-content/plugins/advanced-custom-fields-pro/includes/revisions.php on line 387

Deprecated: Creation of dynamic property acf_validation::$errors is deprecated in /data/6/a/6a361ea2-86f7-4842-bcc4-d9b941aa9bc3/studioecht.com/sub/ableneo/wp-content/plugins/advanced-custom-fields-pro/includes/validation.php on line 28

Deprecated: Creation of dynamic property ACF::$validation is deprecated in /data/6/a/6a361ea2-86f7-4842-bcc4-d9b941aa9bc3/studioecht.com/sub/ableneo/wp-content/plugins/advanced-custom-fields-pro/includes/validation.php on line 215

Deprecated: Creation of dynamic property acf_form_customizer::$preview_values is deprecated in /data/6/a/6a361ea2-86f7-4842-bcc4-d9b941aa9bc3/studioecht.com/sub/ableneo/wp-content/plugins/advanced-custom-fields-pro/includes/forms/form-customizer.php on line 28

Deprecated: Creation of dynamic property acf_form_customizer::$preview_fields is deprecated in /data/6/a/6a361ea2-86f7-4842-bcc4-d9b941aa9bc3/studioecht.com/sub/ableneo/wp-content/plugins/advanced-custom-fields-pro/includes/forms/form-customizer.php on line 29

Deprecated: Creation of dynamic property acf_form_customizer::$preview_errors is deprecated in /data/6/a/6a361ea2-86f7-4842-bcc4-d9b941aa9bc3/studioecht.com/sub/ableneo/wp-content/plugins/advanced-custom-fields-pro/includes/forms/form-customizer.php on line 30

Deprecated: Creation of dynamic property ACF::$form_front is deprecated in /data/6/a/6a361ea2-86f7-4842-bcc4-d9b941aa9bc3/studioecht.com/sub/ableneo/wp-content/plugins/advanced-custom-fields-pro/includes/forms/form-front.php on line 600

Deprecated: Creation of dynamic property acf_form_widget::$preview_values is deprecated in /data/6/a/6a361ea2-86f7-4842-bcc4-d9b941aa9bc3/studioecht.com/sub/ableneo/wp-content/plugins/advanced-custom-fields-pro/includes/forms/form-widget.php on line 34

Deprecated: Creation of dynamic property acf_form_widget::$preview_reference is deprecated in /data/6/a/6a361ea2-86f7-4842-bcc4-d9b941aa9bc3/studioecht.com/sub/ableneo/wp-content/plugins/advanced-custom-fields-pro/includes/forms/form-widget.php on line 35

Deprecated: Creation of dynamic property acf_form_widget::$preview_errors is deprecated in /data/6/a/6a361ea2-86f7-4842-bcc4-d9b941aa9bc3/studioecht.com/sub/ableneo/wp-content/plugins/advanced-custom-fields-pro/includes/forms/form-widget.php on line 36

Notice: Function _load_textdomain_just_in_time was called incorrectly. Translation loading for the complianz-gdpr domain was triggered too early. This is usually an indicator for some code in the plugin or theme running too early. Translations should be loaded at the init action or later. Please see Debugging in WordPress for more information. (This message was added in version 6.7.0.) in /data/6/a/6a361ea2-86f7-4842-bcc4-d9b941aa9bc3/studioecht.com/sub/ableneo/wp-includes/functions.php on line 6170

Notice: Function _load_textdomain_just_in_time was called incorrectly. Translation loading for the wpforms-lite domain was triggered too early. This is usually an indicator for some code in the plugin or theme running too early. Translations should be loaded at the init action or later. Please see Debugging in WordPress for more information. (This message was added in version 6.7.0.) in /data/6/a/6a361ea2-86f7-4842-bcc4-d9b941aa9bc3/studioecht.com/sub/ableneo/wp-includes/functions.php on line 6170

Notice: Function _load_textdomain_just_in_time was called incorrectly. Translation loading for the wordpress-seo domain was triggered too early. This is usually an indicator for some code in the plugin or theme running too early. Translations should be loaded at the init action or later. Please see Debugging in WordPress for more information. (This message was added in version 6.7.0.) in /data/6/a/6a361ea2-86f7-4842-bcc4-d9b941aa9bc3/studioecht.com/sub/ableneo/wp-includes/functions.php on line 6170

Notice: Function _load_textdomain_just_in_time was called incorrectly. Translation loading for the ableneo domain was triggered too early. This is usually an indicator for some code in the plugin or theme running too early. Translations should be loaded at the init action or later. Please see Debugging in WordPress for more information. (This message was added in version 6.7.0.) in /data/6/a/6a361ea2-86f7-4842-bcc4-d9b941aa9bc3/studioecht.com/sub/ableneo/wp-includes/functions.php on line 6170

Deprecated: Creation of dynamic property acf_field_oembed::$width is deprecated in /data/6/a/6a361ea2-86f7-4842-bcc4-d9b941aa9bc3/studioecht.com/sub/ableneo/wp-content/plugins/advanced-custom-fields-pro/includes/fields/class-acf-field-oembed.php on line 31

Deprecated: Creation of dynamic property acf_field_oembed::$height is deprecated in /data/6/a/6a361ea2-86f7-4842-bcc4-d9b941aa9bc3/studioecht.com/sub/ableneo/wp-content/plugins/advanced-custom-fields-pro/includes/fields/class-acf-field-oembed.php on line 32

Deprecated: Creation of dynamic property acf_field_google_map::$default_values is deprecated in /data/6/a/6a361ea2-86f7-4842-bcc4-d9b941aa9bc3/studioecht.com/sub/ableneo/wp-content/plugins/advanced-custom-fields-pro/includes/fields/class-acf-field-google-map.php on line 33

Deprecated: Creation of dynamic property acf_field__group::$have_rows is deprecated in /data/6/a/6a361ea2-86f7-4842-bcc4-d9b941aa9bc3/studioecht.com/sub/ableneo/wp-content/plugins/advanced-custom-fields-pro/includes/fields/class-acf-field-group.php on line 31

Deprecated: Creation of dynamic property acf_field_clone::$cloning is deprecated in /data/6/a/6a361ea2-86f7-4842-bcc4-d9b941aa9bc3/studioecht.com/sub/ableneo/wp-content/plugins/advanced-custom-fields-pro/pro/fields/class-acf-field-clone.php on line 34

Deprecated: Creation of dynamic property acf_field_clone::$have_rows is deprecated in /data/6/a/6a361ea2-86f7-4842-bcc4-d9b941aa9bc3/studioecht.com/sub/ableneo/wp-content/plugins/advanced-custom-fields-pro/pro/fields/class-acf-field-clone.php on line 35
Typed Form groups in Angular - Do Controls in Groups preserve types? - Ableneo

Typed Form groups in Angular – Do Controls in Groups preserve types?


Typed Form Groups in Angular – Are types and nullability of Controls in Groups preserved?

In this article, I would like to explore with you:

  • How to set types and nullability in Form Groups
  • Why is everything in Form Group optional (even when Form Controls are explicitly not nullable)
  • Should we avoid using `getRawValue` — why it can be dangerous?
  • Reducing boilerplate code with Non-Nullable Form Builder

In my previous story about Types of Form Controls, we discussed how can strict types and ‘nonNullable’ flag help us to improve the stability of code (improve checks during compile time) and remove repeating boilerplate code (check if Form Control values are not null). Quick recap:

// simple, but 'if' condition is quite complex
const password = new FormControl(null, { validators: [ Validators.required ] });
if (password.value && (password.value as string).length < 6) {
throw Error('Password is not valid');
}

// ... let`s add type (inferred from default value) -> in 'if' condition it is not required to force type
const password = new FormControl('', { validators: [ Validators.required ] });
if (password.value && password.value.length < 6) {
throw Error('Password is not valid');
}

// ... and set nonNullable to true -> in 'if' we can remove also check for nullability
const password = new FormControl('', { nonNullable: true, validators: [ Validators.required ] });
if (password.value.length < 6) {
throw Error('Password is not valid');
}

But we can also use Form Builder:

const password = this.fb.control('', { nonNullable: true, validators: [ Validators.required ] });
if (password.value.length < 6) {
throw Error('Password is not valid');
}

Types in Form Groups

If Form Control inside Form Group have a type — when we get the value of the whole Form Group, will be type of Controlls preserved?

Let’s consider a simple Form Group. Form Control has not type — well, we need to have complex ‘if’ with forcing of types.

const passwordGroup = new FormGroup({
password: [null, [ Validators.required ] ]
});

if (passwordGroup.value.password && (passwordGroup.value.password as string).length > 0) {
throw Error('Password is not valid');
}

But we can apply what we already know about types and nullability of From Control ( … inside Form Group), and ‘if’ is now less complex / better to read.

const passwordGroup = new FormGroup({
password: new FormControl('', { nonNullable: true, validators: [ Validators.required ] }),
});

if (passwordGroup.value.password && passwordGroup.value.password.length > 0) {
throw Error('Password is not valid');
}

Great, value of Form Group can also have strict type — same as Form Control.

Type is preserved: ‘value’ property of Form Group has properties (or better say, structure), where each property has a type as we defined in the constructor of Form Group

In case you are using Form Builder, you can set a type as well:

constructor(private fb: FormBuilder) {
const passwordGroup = this.fb.group({
password: this.fb.control('', { nonNullable: true, validators: [ Validators.required ] })
});

if (passwordGroup.value.password && passwordGroup.value.password.length > 0) {
throw Error('Password is not valid');
}
}

Nullability in Form Groups

Hey, wait! Why do I need to still check if ‘passwordGroup.value.password’ is not null? I set ‘nonNullable’ flag to true, so why it can be null?

Well, the Form Controls of Form Group can be disabled — hence they can be null.

There is a hack called ‘getRawValue’: but it ignores if Form Control (or Group) in Group is disabled. We should be cautious with it!

if (passwordGroup.getRawValue().password.length > 0) {
throw Error('Password is not valid');
}

Non-Nullable Form Builders

Repeat code set same flags, …

To avoid boilerplates, we can use ‘NonNullableFormBuilder’. It works exactly as Form Builder — but all Form Controls are always Non-Nullable (e.g., set with flag ‘nonNullable: true’)

constructor(private nnFb: NonNullableFormBuilder) {
const passwordGroup = this.nnFb.group({
password: this.nnFb.control('', { validators: [ Validators.required ] })
});

if (passwordGroup.value.password && passwordGroup.value.password.length > 0) {
throw Error('Password is not valid');
}
}

… and again, Angular help us to remove repeating code and flags!

Interesting reading:

Template-Driven Form Groups?

The previous article about Typed Forms has an interesting conclusion:

Typed Forms can help us to reduce code (eliminate IF check for nullability, forcing types, etc.) -> Template-Drive Forms can do it even better!

Form Group is no stranger to Template-Driven Form.

<form #f="ngForm" (ngSubmit)="onSubmit(f)">
  • And then define the Model for Form Group(via the interface, with strict types)
  • Before creating an instance of Model, we of course, need to check if some of the Form Controls have not been disabled (otherwise, our Model would need to have all properties optional)

We recommend watching “Prefer Template-Driven Forms” by Ward Bell. Template-driven forms are recommended by ableneo — check our radar.

Thanks to Marek Vodicka for help with this article!


Typed Form groups in Angular – Do Controls in Groups preserve types? was originally published in ableneo Technology on Medium, where people are continuing the conversation by highlighting and responding to this story.

Related