angularangular-materialreusability

Trying to build a dynamic stepper inside material dialog with reactive forms for a reusable 'automated' assistant component


So I'm trying to build an assistant that shows different steps depending on what data it received. That way I can reuse it for many different flows for every user type (who require individual steps for e.g. registration - sometimes 5 steps, sometimes 3 and so on).

For that I am using a stepper which has different content depending on the use case...

But for some reason my approach to do stuff similiar to this approach (https://georghoeller.dev/angular-material-dynamic-dialog-component/) failed! TLDR: I'm passing TemplateRefs into the dialog and display the content via [ngTemplateOutlet].

I don't know how I can make this scenario work! In react this would be very easy but angular really knows how to overcomplicate things...

Here is the url to my code so far https://stackblitz.com/edit/angular-4zsdop-mfbfbx?file=src%2Fapp%2Fapp.component.ts


Solution

  • Use FormArray with respective FormGroup of different stepper

    initialize your form array in ngOnInit and add diffrent screen/stepper formGrop according to logic something like this.

    ngOnInit() {
        this.formGroup = this._formBuilder.group({
          form: this._formBuilder.array([this.initFormGroup(1)]),
        });
    
      }
    
    initFormGroup(index: number) {
        switch (index) {
          case 1: {
            return this._formBuilder.group({
              type: 1,
              first: new FormControl('', [Validators.required]),
              last: new FormControl('', [Validators.required]),
            });
          }
          case 2: {
            return this._formBuilder.group({
              type: 2,
              address: new FormControl('', [Validators.required]),
            });
          }
          case 3: {
            // logic 
          }
        }
      }
    

    then handle in each stepper html form logic according to form type value.

    <form [formGroup]="formGroup">
          <mat-horizontal-stepper  formArrayName="form">
            <mat-step [formGroupName]="i" *ngFor="let elements of formGroup.controls.form.controls; let i = index">
              <ng-template matStepLabel>Step {{i + 1}}</ng-template>
              <div *ngIf="getFormType(i) == 1">
                <mat-form-field>
                  <input
                    matInput
                    placeholder="firstName"
                    formControlName="first"
                    required
                  />
                </mat-form-field>
             </div>
             <div *ngIf="getFormType(i) == 2">
                <!- different form group html here -->
             </div>
            <div>
              <button mat-button matStepperPrevious>Back</button>
              <button mat-button matStepperNext>Next</button>
            </div>
            </mat-step>
          </mat-horizontal-stepper>
        </form>
    

    here is stackblitz link.