How can i send my nested formGroupName to my input component connected to control value accessor?

463 Views Asked by At

I have custom component which is connected to control value accessor. In this component i am building dynamically my form tags like input,textarea etc...

It is working everything fine - but i have problem when i try to send nested form group. So form group in form group.

I have builded this formGroup

  registerFG = this.builder.group({
    password_register: ['', [Validators.required]],

    email_register_group: this.builder.group({
      email_register: ['', [Validators.required, CustomValidators.emailDomain('yourcompanyname.com')]],
      email_register_confirm: ['', [Validators.required]],
    }),

si if i want to send password_register i would do it in my parent component as

  <app-form-group inputType="password" cssTemplate="white" formControlName="password_register" [data]="{ field: 'password_register', label: 'Password' }"></app-form-group>

but this is just one formControl inside my main formGroup registerFG

Now i need to send the whole formGroup - email_register_group which is nested inside my main formGroup - registerFG.

i treid with custom sub-component

parent compo

<app-sub-form-group formGroupName=email_register_group></app-sub-form-group>

sub-component HTML

<ng-container [formGroup]="controlContainer.control">
       <app-form-group cssTemplate="white" formControlName=email_register [data]="{ field: 'email_register', label: 'Email' }"></app-form-group>
       <app-form-group cssTemplate="white" formControlName=email_register_confirm [data]="{ field: 'email_register_confirm', label: 'Confirm Email' }"></app-form-group>

</ng-container>

sub-component TS

 @Input() public formGroupName: string;
  
  constructor(public controlContainer: ControlContainer) { 
   
  }

cutom-component connected to the control value accessor

@Component({
  selector: 'app-form-group',
  templateUrl: './form-group.component.html',
  styleUrls: ['./form-group.component.scss'],
  // providers: [{
  //   provide: NG_VALUE_ACCESSOR,
  //   useExisting: forwardRef(() => FormGroupComponent),
  //   multi: true
  // }
  // ],
  
})
export class FormGroupComponent implements OnInit {
 constructor(@Self() @Optional() public control: NgControl,
  private authService: AuthService, private builder: FormBuilder) {
     // here i keep geting just the ngControl with formControl inside but now the formGroup with
     // two formControls inside
     console.log(control);
  }
}

how can i get my formGroup with two formControls inside -email_register_group`

as suggested here:

Create a reusable FormGroup

but when i to the same thing i9 keep getting just the control inside - not the formGroup

1

There are 1 best solutions below

1
On

Whenever you want to do this, you need to use the ControlValueAccessor provided by the Angular.

So your code turns out to be something like this:

PS: This is not the exact solution but it caters your need at the moment

// You will enable the commented code
@Component({
  selector: 'app-form-group',
  templateUrl: './form-group.component.html',
  styleUrls: ['./form-group.component.scss'],
  providers: [{
    provide: NG_VALUE_ACCESSOR,
    useExisting: forwardRef(() => FormGroupComponent),
    multi: true
  }],
  
})

// Your component should implement CONTROLVALUEACCESSOR
export class FormGroupComponent implements OnInit, ControlValueAccessor {

// Here you will write a couple of methods to enable your custom component to register all the changes 

   /**
   * @param val The current value to be overwritten
   */
  writeValue(val: any): void {
    this.value = val;
  }

  /**
   * @param obj The callback function to register
   */
  registerOnChange(fn: any): void {}

  /**
   * @param obj The callback function to register.
   */
  registerOnTouched(fn: any): void {}

  /**
   * @param isDisabled The disabled status to set on the element.
   */
  setDisabledState?(isDisabled: boolean): void {}

}

You may want to use these methods in your custom component to make it register the formgroups and all.