2
votes

I want to create a custom component on top of angular material mat-select. The custom component should support both reactive form and not a reactive form.

The custom component get inputs as:
@Input() group: FormGroup; @Input() controlName: string;

the custom component HTML

<mat-form-field [formGroup]="group">
  <mat-select placeholder="Favorite food" [formControlName]="controlName">
    <mat-option *ngFor="let food of foods" [value]="food.value">
      {{food.viewValue}}
    </mat-option>
  </mat-select>
</mat-form-field>

it works fine when I pass the group and the controlName but when I want to use the same component without reactive form I get error: "formGroup expects a FormGroup instance. Please pass one in"

<!-- With Reactive Form -->
<app-custom-dropdown [group]="form" [controlName]="'foods'"></app-custom-dropdown>

<!-- Without Reactive Form -->
<app-custom-dropdown></app-custom-dropdown>

My Question is how I can support both cases when the custom component used with reactive form and in other time without reactive form.

stackblitz Example

1
Why do you need it without reactive form? What is the use of the component ?Niladri
This custom component is a drop-down with closed os types that I use in a big project. In the project we sometimes use forms as template driven and and sometimes reactive formofir fridman

1 Answers

1
votes

when you are using template form and calling your component like so

<app-custom-dropdown></app-custom-dropdown>

you do not pass formGroup, so in you app-custom-dropdown component @Input() group will be undefined, which you are passing in template

<mat-form-field [formGroup]="group">

so here you need to add condition to not pass group if it's undefined

UPDATE here is one of possible examples

<ng-container *ngTemplateOutlet='group ? reactive : template'>
</ng-container>

<ng-template #reactive>
  <mat-form-field [formGroup]="group">
    <mat-select placeholder="Favorite food" [formControlName]="controlName">
      <mat-option *ngFor="let food of foods" [value]="food.value">
        {{food.viewValue}}
      </mat-option>
    </mat-select>
  </mat-form-field>
</ng-template>

<ng-template #template>
  <mat-form-field>
    <mat-select placeholder="Favorite food" >
      <mat-option *ngFor="let food of foods" [value]="food.value">
        {{food.viewValue}}
      </mat-option>
    </mat-select>
  </mat-form-field>
</ng-template>