angular - Angular Material 2 Stepper Controls

user340950934589034 picture user340950934589034 · Oct 25, 2017 · Viewed 9k times · Source

I set up a linear stepper using the Angular Material 2 Stepper.

I have forms in different components (component-a, component-b, component-c). In my main container component (container-component) I want to have linear stepper that 'steps' through each component when their form is valid.

Is there some sort of functionality to talk up to the stepControl in the stepper to make it properly work?

I have attached documentation for the stepper and a StackBlitz version of the application. Also, a link to the repo I have working as well.

Material Stepper Component: https://material.angular.io/components/stepper/overview

StackBlitz: https://stackblitz.com/edit/angular-material2-issue-mjmu9u?file=app/app.component.ts

Github: https://github.com/sam11385

Answer

prusik picture prusik · Dec 5, 2017

We had the exact same problem, and found a working solution after several days of trial and error. Basically since the steps are divided into several components that each define a form, and that their corresponding stepControl must be in the parent, the FormGroup in the child component must be sent to the parent component that defines the stepper. After creating the FormGroup, emit an event and have the parent listen to that event, and pass the FormGroup through that event. You can apply this for all children, creating a separate event for each and a separate listener in the parent for each emitter.

In the child component:

  1. declare the event

    @Output() notify: EventEmitter<FormGroup> = new EventEmitter<FormGroup>();                                                                                                         
    
  2. emit the formGroup to the parent component

    this.notify.emit(this.myFormGroup);                                                                                                                                                
    

In the parent component containing the mat-stepper's stepControl(s):

  1. In the component(.ts), add a function that will receive and set the formgroup:

    myFormGroup: FormGroup;
    onNotify(formGroup: FormGroup): void {
      this.myFormGroup = formGroup;
    }
    
  2. In the html, add the notification listener:

    <mat-step [completed]="false" [stepControl]="myFormGroup">
      <ng-template matStepLabel>Step 1</ng-template>
      <app-child (notify)='onNotify($event)'></app-child>
    </mat-step>                                                                                                                                            
    

Nested components explanations: https://www.themarketingtechnologist.co/building-nested-components-in-angular-2/