Home > Software design >  Reuse angular component with form from a parent component without form
Reuse angular component with form from a parent component without form

Time:07-22

I have a angular component which uses a form group and can be used to show a readonly view based on an input @Input() isEditModeActive: boolean;. The component works fine when the parent component has form .

@Component({
  selector: 'bifrost-organization-financial',
  templateUrl: './organization-financial.component.html',
})
export class OrganizationFinancialComponent implements OnInit {
  readonly MAX_NAME_LENGTH: number = 50;
  readonly MAX_IBAN_LENGTH: number = 255;
  readonly MAX_OTHER_NUMBER_LENGTH: number = 50;
  readonly MAX_BIC_LENGTH: number = 255;
  currencies: Currency[] = currencies;
  bankAccount: BankAccount;
  bankAccountTypes: BankAccountType[] = bankAccountTypes;
  organizationFinancialFormGroup: FormGroup = new FormGroup({});

  @Input() errorCodes: ErrorCode[];
  @Input() customer: Organization;
  @Input() isEditModeActive: boolean;

  constructor(public readonly controlContainer: ControlContainer) {}

  ngOnInit(): void {
    this.organizationFinancialFormGroup = this.controlContainer
      .control as FormGroup;
    if (this.customer.bankAccounts.length === 0) {
      this.customer.bankAccounts = [new BankAccount()];
    }
    this.bankAccount = this.customer.bankAccounts[0];

    this.organizationFinancialFormGroup.addControl(
      'currency',
      new FormControl(this.customer.currency, [])
    );

    this.organizationFinancialFormGroup.addControl(
      'name',
      new FormControl(this.bankAccount.name, [
        Validators.maxLength(this.MAX_NAME_LENGTH),
      ])
    );

    this.organizationFinancialFormGroup.addControl(
      'type',
      new FormControl(this.bankAccount.type, [Validators.required])
    );

    let bankAccountNumber: String = '';
    if (this.bankAccount.type === 'SEPA') {
      bankAccountNumber = this.bankAccount.number;
    }

    this.organizationFinancialFormGroup.addControl(
      'iban',
      new FormControl(bankAccountNumber, [
        Validators.maxLength(this.MAX_IBAN_LENGTH),
        ibanValidator(),
      ])
    );

    bankAccountNumber = '';
    if (this.bankAccount.type === 'OTHER') {
      bankAccountNumber = this.bankAccount.number;
    }

    this.organizationFinancialFormGroup.addControl(
      'otherBankAccountNumber',
      new FormControl(bankAccountNumber, [
        Validators.maxLength(this.MAX_OTHER_NUMBER_LENGTH),
        Validators.pattern(/^[A-Za-z0-9\s]*$/),
      ])
    );

    this.organizationFinancialFormGroup.addControl(
      'bic',
      new FormControl(this.bankAccount.bic, [
        Validators.maxLength(this.MAX_BIC_LENGTH),
      ])
    );
  }
}

I want to reuse the component only for the read only view , but in this case the parent component does not have any FormGroup, But the code breaks with the below error :

 NullInjectorError: R3InjectorError(CustomersModule)[ControlContainer -> ControlContainer -> ControlContainer -> ControlContainer]: 
  NullInjectorError: No provider for ControlContainer!

Is it possible to reuse this component from a parent component without a formGroup ?

CodePudding user response:

You can try to add @Optional() decorator when injecting ControlContainer like that:

constructor(@Optional() public readonly controlContainer: ControlContainer) {}

Then you also probably need if statement in ngOnInit

ngOnInit(): void {
  if (!!this.controlContainer) {
    // do your stuff here   
  } else {
    // readonly mode stuff here
  }
}
  • Related