Alternativas
this.form.get('fullname').get('last')
this.form.get('fullname.last')
this.fullName.get('last')
Cuando trabajas con formularios reactivos en Angular, no siempre basta con un solo nivel de campos. Hay escenarios donde la información llega del backend en subobjetos o donde una base de datos NoSQL estructura los datos de forma anidada. Saber crear múltiples FormGroups dentro de un mismo formulario te permite mantener la coherencia entre tu modelo de datos y la interfaz, sin transformaciones innecesarias.
¿Por qué necesitas FormGroups anidados en formularios reactivos?
Un FormGroup anidado es, en esencia, un grupo de controles que vive dentro de otro grupo. El ejemplo más claro es una dirección: tiene calle, código postal, ciudad y otros campos que conviene agrupar en un solo objeto. Lo mismo aplica para un nombre completo, donde separas name y last name en campos independientes pero los mantienes dentro de un subobjeto llamado fullName [01:05].
Esta técnica resulta especialmente útil en tres situaciones:
¿Cómo se crea un subobjeto dentro del FormGroup principal?
En el código del componente, donde antes existía un simple FormControl llamado name, se reemplaza por un objeto que contiene sus propios campos. El grupo pasa a llamarse fullName y dentro se definen los controles name y last, cada uno con sus validadores como expresiones regulares [02:00].
Un detalle importante es que Angular no interpreta automáticamente un objeto literal como un subgrupo. Es necesario utilizar el FormBuilder para crear explícitamente ese grupo interno con this.fb.group({...}). Si omites este paso, el valor del subgrupo llega como null y el template genera errores [05:48].
typescript this.form = this.fb.group({ fullName: this.fb.group({ name: ['', [Validators.required, Validators.pattern(/^[a-zA-Z]{1,10}$/)]], last: ['', [Validators.required, Validators.pattern(/^[a-zA-Z]{1,10}$/)]] }), email: ['', Validators.required], phone: ['', Validators.required] });
¿Cómo acceder a los controles de un grupo anidado?
La referencia a un campo dentro de un subgrupo cambia respecto a un control directo. Para obtener el FormControl de name, primero accedes al grupo fullName y luego al control específico [03:15].
typescript get nameField() { return this.form.get('fullName')?.get('name'); }
get lastField() { return this.form.get('fullName')?.get('last'); }
Angular también ofrece una sintaxis abreviada con notación de punto que simplifica el código. En lugar de encadenar dos .get(), puedes escribir this.form.get('fullName.name') y this.form.get('fullName.last') [07:35]. Ambas formas son válidas; la segunda es menos verbosa y más legible.
¿Qué cambia en el template HTML con FormGroups anidados?
En el HTML, los campos que pertenecen al subgrupo deben estar envueltos en un contenedor que utilice la directiva formGroupName. Este contenedor indica a Angular que los controles internos pertenecen al grupo fullName y no al formulario raíz [04:00].
html
<div formGroupName="fullName"> <input formControlName="name" placeholder="Nombre"> <input formControlName="last" placeholder="Apellido"> </div>Dentro de ese div, las validaciones y mensajes de error siguen funcionando exactamente igual. Solo necesitas asegurarte de que el getter apunte correctamente al control anidado.
¿Cómo se estructura el objeto resultante al enviar el formulario?
Cuando envías el formulario, el valor resultante refleja la estructura anidada. El objeto principal contiene una propiedad fullName que a su vez es un objeto con name y last [06:55].
{ "fullName": { "name": "Nicolás", "last": "Molina" }, "email": "ejemplo@correo.com", "phone": "123456789" }
Esta estructura es ideal para enviarla directamente a una API sin necesidad de transformar los datos. Además, los FormGroups anidados permiten realizar validaciones grupales, es decir, validar la relación entre varios campos dentro del mismo grupo, aunque eso requiere una implementación más avanzada.
Si ya dominas formularios reactivos básicos, incorporar subgrupos te dará mayor control sobre formularios complejos. ¿Has tenido que trabajar con estructuras anidadas más profundas? Comparte tu experiencia en los comentarios.
Cuando trabajas con formularios reactivos en Angular, no siempre basta con un solo nivel de campos. Hay escenarios donde la información llega del backend en subobjetos o donde una base de datos NoSQL estructura los datos de forma anidada. Saber crear múltiples FormGroups dentro de un mismo formulario te permite mantener la coherencia entre tu modelo de datos y la interfaz, sin transformaciones innecesarias.
Un FormGroup anidado es, en esencia, un grupo de controles que vive dentro de otro grupo. El ejemplo más claro es una dirección: tiene calle, código postal, ciudad y otros campos que conviene agrupar en un solo objeto. Lo mismo aplica para un nombre completo, donde separas name y last name en campos independientes pero los mantienes dentro de un subobjeto llamado fullName [01:05].
Esta técnica resulta especialmente útil en tres situaciones:
En el código del componente, donde antes existía un simple FormControl llamado name, se reemplaza por un objeto que contiene sus propios campos. El grupo pasa a llamarse fullName y dentro se definen los controles name y last, cada uno con sus validadores como expresiones regulares [02:00].
Un detalle importante es que Angular no interpreta automáticamente un objeto literal como un subgrupo. Es necesario utilizar el FormBuilder para crear explícitamente ese grupo interno con this.fb.group({...}). Si omites este paso, el valor del subgrupo llega como null y el template genera errores [05:48].
typescript this.form = this.fb.group({ fullName: this.fb.group({ name: ['', [Validators.required, Validators.pattern(/^[a-zA-Z]{1,10}$/)]], last: ['', [Validators.required, Validators.pattern(/^[a-zA-Z]{1,10}$/)]] }), email: ['', Validators.required], phone: ['', Validators.required] });
La referencia a un campo dentro de un subgrupo cambia respecto a un control directo. Para obtener el FormControl de name, primero accedes al grupo fullName y luego al control específico [03:15].
typescript get nameField() { return this.form.get('fullName')?.get('name'); }
get lastField() { return this.form.get('fullName')?.get('last'); }
Angular también ofrece una sintaxis abreviada con notación de punto que simplifica el código. En lugar de encadenar dos .get(), puedes escribir this.form.get('fullName.name') y this.form.get('fullName.last') [07:35]. Ambas formas son válidas; la segunda es menos verbosa y más legible.
En el HTML, los campos que pertenecen al subgrupo deben estar envueltos en un contenedor que utilice la directiva formGroupName. Este contenedor indica a Angular que los controles internos pertenecen al grupo fullName y no al formulario raíz [04:00].
html
<div formGroupName="fullName"> <input formControlName="name" placeholder="Nombre"> <input formControlName="last" placeholder="Apellido"> </div>Dentro de ese div, las validaciones y mensajes de error siguen funcionando exactamente igual. Solo necesitas asegurarte de que el getter apunte correctamente al control anidado.
Cuando envías el formulario, el valor resultante refleja la estructura anidada. El objeto principal contiene una propiedad fullName que a su vez es un objeto con name y last [06:55].
{ "fullName": { "name": "Nicolás", "last": "Molina" }, "email": "ejemplo@correo.com", "phone": "123456789" }
Esta estructura es ideal para enviarla directamente a una API sin necesidad de transformar los datos. Además, los FormGroups anidados permiten realizar validaciones grupales, es decir, validar la relación entre varios campos dentro del mismo grupo, aunque eso requiere una implementación más avanzada.
Si ya dominas formularios reactivos básicos, incorporar subgrupos te dará mayor control sobre formularios complejos. ¿Has tenido que trabajar con estructuras anidadas más profundas? Comparte tu experiencia en los comentarios.
Alternativas
this.form.get('fullname').get('last')
this.form.get('fullname.last')
this.fullName.get('last')
Muy interesante para el Backend. Resuelve mucho la vida
Huy excelente clase, claro q nos arregla la existencia en el backend, gracias nicobytes
Pesimo que se traben los videos.
Aplicando FormGroup anidados en el trabajo, gracias platzi :)

Magnifica clase, se facilita el control.
Los videos se desfasan y no se puede seguir el hilo
Es buena práctica crear un @injectable y, utilizarlo como un método global que contenga x cantidad de otros servicios?
Hola espero alguien me pueda ayudar, tengo un componente input genérico el cual recibe por @Input() el FormGroup y el formControlName el problema es que al usar FormGroups anidados no puedo acceder al formControl alguien sabe como puedo hacerlo?
Hola compañeros, pasa de que cuando le doy clic al botón de name y de lastName para que en consola se muestre el valor que tienen, automaticamente se hace un submit de todo el formulario, osea, se ejecuta la función save. Qué está pasando ahí?
Daniel Camacho
Leonardo Zuluaga
Raúl López Hernando
Alfonso Navarro
Company_adminPatrick Feeney
Jose Luis Junior Perez Gil
Henry Fuentes
David Elizalde
Seba Cardoso
Kriscia Zapata
Alvaro Alejandro Pavon Torres
Gustavo Restrepo
Massimo Di Berardino
Christian Guevara
Alternativas
this.form.get('fullname').get('last') this.form.get('fullname.last') this.fullName.get('last')
Gracias crack!
Muy interesante para el Backend. Resuelve mucho la vida
Huy excelente clase, claro q nos arregla la existencia en el backend, gracias nicobytes
Pesimo que se traben los videos.
Aplicando FormGroup anidados en el trabajo, gracias platzi :)
Magnifica clase, se facilita el control.
Los videos se desfasan y no se puede seguir el hilo
Este curso ya quedo obsoleto actualmente
Es buena práctica crear un @injectable y, utilizarlo como un método global que contenga x cantidad de otros servicios?
Hola espero alguien me pueda ayudar, tengo un componente input genérico el cual recibe por @Input() el FormGroup y el formControlName el problema es que al usar FormGroups anidados no puedo acceder al formControl alguien sabe como puedo hacerlo?
Hola compañeros, pasa de que cuando le doy clic al botón de name y de lastName para que en consola se muestre el valor que tienen, automaticamente se hace un submit de todo el formulario, osea, se ejecuta la función save. Qué está pasando ahí?
Hola Gustavo, podrías compartir una captura o fragmento de código o tu repositorio para poder ayudarte de mejor manera :)
Hola Gustavo, esto sucede porque el form detecta cualquier boton con el evento submit, si vas a gregar un boton que no envie el contenido del formulario o realice un submit, agrega **preventDefault ** a tu funcion. Ejemplo:
getNameValue(event): void { event.preventDefault(); console.log(this.nameField.value); }
Con esto estas diciendo al componente que no realice su funcionalidad por defecto (en este caso la accion de submit), si no la que tu quieras que realice.