jgcarrillo
jgcarrillo

Reputation: 186

Angular 14: Implement Factory pattern

I want to implement Factory pattern in Angular.

The point is, I need to create several forms but every form has its owns properties so I thought the best approach was to create a Factory of forms and depends of the type the factory will render one form or another.

app.component.html

<app-form-builder [type]="'phoneForm'"></app-form-builder>

form-builder.component.ts

interface FormMapping {
  [key: string]: ComponentRef<FormNameComponent | FormPhoneComponent>;
}

@Input() type: string = '';

constructor(public viewContainerRef: ViewContainerRef) {}

getFormTypes(type: string) {
  const formMapping: FormMapping = {
    nameForm: this.viewContainerRef.createComponent(FormNameComponent),
    phoneForm: this.viewContainerRef.createComponent(FormPhoneComponent),
  };

  formMapping[type];
}

ngOnInit(): void {
  this.getFormTypes(this.type);
}

The form components are not relevant since the phoneForm displays a form with a input type number and the nameForm displays a form with a input type text.

The approach works if I use multiple If's but I don't know why don't if I use the object because it renders the two forms at the same time.

getFormType(type: string) {
  if (type === 'nameForm') {
    this.viewContainerRef.createComponent(FormNameComponent);
  }

  if (type === 'phoneForm') {
    this.viewContainerRef.createComponent(FormPhoneComponent);
  }
}

Demo @ StackBlitz

I have followed this StackOverflow question but this example shows how to instantiate a Service but in my case I want to instantiate a component.

Upvotes: 0

Views: 449

Answers (1)

Zsolt Balint
Zsolt Balint

Reputation: 775

your problem resides in the mapping creation part:

 const formMapping: FormMapping = {
      nameForm: this.viewContainerRef.createComponent(FormNameComponent),
      phoneForm: this.viewContainerRef.createComponent(FormPhoneComponent),
    };

When you are creating mapping basically are you instantiating also teh components by calling "createComponent".

You should create mapping like this:

 const formMapping: FormMapping = {
      nameForm: FormNameComponent,
      phoneForm: FormPhoneComponent,
    };

End just call create based on the value:

 this.viewContainerRef.createComponent(getFormTypes('...'));

Upvotes: 1

Related Questions