Search code examples
angulartypescriptangular-forms

Angular 14 Custom Form Group component not rendering


I'm creating a custom component for a FormGroup that won't render for some reason. My overall form looks like this

export class SvgParserComponent{

  SvgForm : FormGroup<SvgForm> = new FormGroup<SvgForm>({
    title: new FormControl<string>(''),
    graphicId: new FormControl<string>(''),
    svgInput: new FormControl<string>(''),
    viewBox: new FormGroup<ViewBoxParams>({
      x: new FormControl<string>(''),
      y: new FormControl<string>(''),
      width: new FormControl<string>(''),
      height: new FormControl<string>('')
    }),
    styling: new FormGroup<StylingParams>({
      globalStyles: new FormControl<string>(''),
      mediaQueries: new FormArray<FormGroup<MediaQueryParams>>([])
    })
  });

  constructor(){}

  //other code

  }

I made a component for text input which looks like this.

text-input.component.ts

@Component({
  selector: 'text-input',
  templateUrl: './text-input.component.html',
  styleUrls: ['./text-input.component.css'],
  providers: [
    {
      provide: NG_VALUE_ACCESSOR,
      useExisting : TextInputComponent,
      multi: true
    }
  ]
})
export class TextInputComponent implements ControlValueAccessor{

  @Input() label!: string;
  
  field  = '';

  onChange : any = () =>{};
  onTouch : any = () => {};

  set value(val : any){
    this.field = val;
    this.onChange(val);
    this.onTouch(val);
  }

  writeValue(value: any){ this.value = value; }

  registerOnChange(fn: any){ this.onChange = fn; }

  registerOnTouched(onTouched: Function){ this.onTouch = onTouched; }

}

text-input.component.html

<label>
  <span>{{label}}</span>
  <input type="text" [(ngModel)]="value" />
</label>

I created another custom input for the viewBox group that uses the text-input component which looks like this

viewbox-input.component.ts

@Component({
  selector: 'viewbox-input',
  templateUrl: './viewbox-input.component.html',
  styleUrls: ['./viewbox-input.component.css'],
  providers: [
    {
      provide: NG_VALUE_ACCESSOR,
      useExisting: ViewboxInputComponent,
      multi: true
    }
  ]
})
export class ViewboxInputComponent implements ControlValueAccessor{

  ViewboxForm : FormGroup<ViewBoxParams> = new FormGroup<ViewBoxParams>({
    x: new FormControl<string>(''),
    y: new FormControl<string>(''),
    width: new FormControl<string>(''),
    height: new FormControl<string>('')
  });

  writeValue(value: any){
    if(value){ this.ViewboxForm.setValue(value); }
  }

  registerOnChange(fn: any){ this.ViewboxForm.valueChanges.subscribe(fn); }

  registerOnTouched(onTouched: Function){}

}

viewbox-input.component.html

<section class="shell" [formGroup]="ViewboxForm">
  <p>ViewBox</p>
  <text-input formControlName="x" [label]="'x'"></text-input>
  <text-input formControlName="y" [label]="'y'"></text-input>
  <text-input formControlName="width" [label]="'width'"></text-input>
  <text-input formControlName="height" [label]="'height'"></text-input>
</section>

Inside the parent component where the entire form is defined I use the viewbox-input component like this

<viewbox-input formGroupName="viewBox"></viewbox-input>

This for some reason won't render while also not throwing any type of errors in the console. I've switch the text-input component with plain <input type="text" /> inputs and got the same result. I also switched formGroupName with [formGroup]="SvgForm.controls.viewBox" and tried the same with the formControls used inside te component but it just silently fails some kind of way. Does anybody know what I'm doing wrong here?

Here's a stackblitz of the app.


Solution

  • Is your 'ViewboxComponentModule' correctly imported in your 'SvgParserModule' ?
    It doesn not appear in your stackblitz link.