If you hookup the MatStepper to a FormGroup and then set the url based on the form's current value you can get the intended functionality:
// setup controls
coachIdControl = new FormControl(null, [Validators.required]);
dateControl = new FormControl(null, [Validators.required]);
formGroup = new FormGroup({
coachId: this.coachIdControl,
date: this.dateControl
});
To bind the form to the url and vice versa you can:
// take values from the url and use to populate the form and set current step
// (you can also use queryMap to use /coach/:id/date/:date url)
// if the user refreshes the page, the form will repopulate from the query
this._route.queryParamMap.subscribe(query => {
if(query.has('coachId') && this.coachIdControl.value !== query.get('coachId')){
this.coachIdControl.setValue(query.get('coachId'));
this.matStepper.selectedIndex = 1;
}
let date = moment.isMoment(this.dateControl.value) ? this.dateControl.value.format('YYYY-MM-DD') : null;
if(query.has('date') && date !== query.get('date')){
this.dateControl.setValue(query.get('date'));
this.matStepper.selectedIndex = 2;
}
this.formGroup.updateValueAndValidity();
});
// if the form changes, update the query params in the url
this.formGroup.valueChanges.subscribe(value => {
this._router.navigate(['.'], {queryParams: {
coachId: value.coachId,
date: moment.isMoment(value.date) ? value.date.format('YYYY-MM-DD') : null
}});
});
The full example is here: StackBlitz - angular-material-routed-stepper
Update: Reset Steps
To remove url query values when stepping back you can listen for the selectionChange event and reset the values for steps that come after the selected step:
this.matStepper.selectionChange.subscribe((event: StepperSelectionEvent) => {
switch(event.selectedIndex){
case 0:
this.dateControl.setValue(null);
case 1:
this.confirmControl.setValue(null);
}
});
(Since the switch statements falls through, every step after the selected step will be reset.)
setValue will, in-turn, emit the valueChanges event which will update the url query.
The above Stackblitz is updated with this functionality.
router.navigate(['./childURL'])?