Recently, I followed the angular update Guide here from Angular 9 to 10. I updated core, cli, material, cdk, ngrx etc. and I did an 'ng update' to make sure everything has migrated properly.
Then I complied and built it without any errors/warnings, everything works fine, except the cdk stepper, it doesn't show any of the cdk step and content under
<cdk-stepper></cdk-stepper>
Image : Angular 10
But it is working fine in Angular 9
Image: Angular 9
Here is my customise cdk stepper component .ts and html:
import { animate, AnimationEvent, state, style, transition, trigger } from '@angular/animations';
import { CdkStepper, StepContentPositionState } from '@angular/cdk/stepper';
import { AfterContentInit, ChangeDetectionStrategy, Component, EventEmitter, Input, Output } from '@angular/core';
import { Subject } from 'rxjs/internal/Subject';
import { distinctUntilChanged, takeUntil } from 'rxjs/operators';
@Component({
selector: 'cdk-stepper',
templateUrl: './cdk-stepper.component.html',
styleUrls: ['./cdk-stepper.component.scss'],
providers: [{ provide: CdkStepper, useExisting: CdkStepperComponent }],
animations: [trigger('stepTransition', [
state('previous', style({
transform: 'translateY(-100%)', zIndex: -1,
opacity: 0
})),
state('current', style({
transform: 'translateY(0)', zIndex: 0,
opacity: 1
})),
state('next', style({
transform: 'translateY(100%)', zIndex: -1,
opacity: 0
})),
transition('* => *', animate('700ms cubic-bezier(0.35,0,0.25,1)'))
])],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class CdkStepperComponent extends CdkStepper
implements AfterContentInit {
currentVerticalLine = {
'height': '20vh',
'transition': 'height 200ms ease',
'top': '-3%'
}
@Output() readonly animationDone: EventEmitter<void> = new EventEmitter<void>();
_animationDone = new Subject<AnimationEvent>();
@Input() stepHeaderNumber;
stepHeaderTitle = ['Scan Tenant', 'Mailbox Rules', 'Audit Logs', 'Summary']
@Input('setSelectedIndex') set setSelectedIndex(index: number) {
this.updateIndex(index);
}
@Output() updateMyIndex: EventEmitter<number> = new EventEmitter();
updateIndex(index: number) {
console.log(index)
this.selectedIndex = index;
this.updateMyIndex.emit(index);
}
onClick(index: number): void {
this.selectedIndex = index;
}
ngAfterContentInit() {
console.log(this.steps)
// Mark the component for change detection whenever the content children query change
this.steps.changes.pipe(takeUntil(this._destroyed)).subscribe(() => {
this._stateChanged();
});
this._animationDone.pipe(
// distinctUntilChanged to avoid emitting the same event twice,
// as some browsers callback invokes '.done' twice.
distinctUntilChanged((x, y) => {
return x.fromState === y.fromState && x.toState === y.toState;
}),
takeUntil(this._destroyed)
).subscribe(event => {
if ((event.toState as StepContentPositionState) === 'current') {
this.animationDone.emit();
}
});
}
checkProgress(index) {
if (this.selectedIndex > index) {
return true;
}
else {
return false;
}
}
}
<div class="container">
<app-vertical-steps [steps]="steps" [titles]="stepHeaderTitle" [(current)]="selectedIndex" (currentChange)="updateIndex($event)"></app-vertical-steps>
<div class="cdk-vertical-content-container">
<div *ngFor="let step of steps; let i=index;" class="cdk-vertical-content ng-trigger ng-trigger-stepTransition"
[@stepTransition]="_getAnimationDirection(i)" [attr.tabindex]="selectedIndex === i ? 0 : null"
[id]="_getStepContentId(i)" (@stepTransition.done)="_animationDone.next($event)"
[attr.aria-labelledby]="_getStepContentId(i)" [attr.aria-expanded]="selectedIndex === i">
<mat-card class="cdk-card" [class.hidden]="selectedIndex !== i">
<ng-container [ngTemplateOutlet]="step.content"></ng-container>
</mat-card>
</div>
</div>
</div>
And the following is my parent component container that using the cdk-stepper as a child:
import { Component, OnDestroy, OnInit } from "@angular/core";
import { select, Store } from '@ngrx/store';
import { combineLatest } from 'rxjs';
import { GraphActions } from 'src/app/actions';
import { fetchSummaries } from 'src/app/entities/event-summary/event-summary.actions';
import * as fromRoot from 'src/app/reducers';
@Component({
selector: "app-container",
templateUrl: "./container.component.html",
styleUrls: ["./container.component.scss"]
})
export class ContainerComponent implements OnInit, OnDestroy {
pending = false;
myIndex = 0;
constructor(
private store: Store<fromRoot.State>
) { }
ngOnInit() {
combineLatest(
this.store.pipe(select(fromRoot.getInitialized)),
this.store.pipe(select(fromRoot.inboxRulesFetched)),
this.store.pipe(select(fromRoot.getUsers))
).subscribe(([initialized, fetched, users]) => {
if (initialized) {
this.store.dispatch(fetchSummaries());
if (!fetched) {
for (let index = 0; index < users.length; index++) {
const identity = users[index].id;
const mail = users[index].mail;
if (mail !== null && users[index].userType !== 'Guest') {
this.store.dispatch(GraphActions.fetchGraphInboxRules({ identity }))
}
}
}
}
})
}
ngOnDestroy() {
}
setIndex($event) {
this.myIndex = $event;
}
setPendingScan($event) {
this.pending = $event;
}
}
<div class="container">
<app-log-scanning-icon [pendingScan]="pending"></app-log-scanning-icon>
<cdk-stepper [setSelectedIndex]="myIndex" (updateMyIndex)="setIndex($event)">
<cdk-step>
<app-introduction (indexChange)="setIndex($event)" (pendingScan)="setPendingScan($event)"></app-introduction>
</cdk-step>
<cdk-step>
<app-mailboxes (indexChange)="setIndex($event)" [currentStep]="myIndex === 1"></app-mailboxes>
</cdk-step>
<cdk-step>
<app-audit-logs (indexChange)="setIndex($event)" [currentStep]="myIndex === 2"></app-audit-logs>
</cdk-step>
<cdk-step>
<app-summary (indexChange)="setIndex($event)" [currentStep]="myIndex === 3"></app-summary>
</cdk-step>
</cdk-stepper>
</div>
I will be appreciated if anyone can help or providing any hints why it doesn't work on angular 10.. Or any part of my code is delegrated? Thanks.
P.S. here is my package.json version list:package.json
Faced the same problem. The problem is ngAfterContentInit() in your CdkStepperComponent component. In version 10 you have to call super.ngAfterContentInit() of the CdkStepper parent class, the steps are initialized in this method since version 10 apparently.