When I attempt to update my Angular component using a subject in Storybook by calling subject.next(false)
, I encounter an issue. The instance property of the component updates, but it does not reflect in the canvas panel.
Here is my loading component:
@Component({
selector: 'app-loading',
templateUrl: './loading.component.html'
})
export class LoadingComponent implements OnInit, OnDestory {
// control the loading icon show or not
public state: boolean = true;
private subscription: Subscription = null;
constructor(private loadingSerivce: LoadingService) {}
ngOnInit(): void {
this.subscription = this.loadingService.state.subscribe(state => {
this.updateState(state);
console.log(this.state);
});
}
ngOnDestroy(): void {
if (this.subscription) {
this.subscription.unsubscribe();
}
}
updateState(state: boolean): void {
this.state = state;
}
}
Additionally, here is my loading service:
@Injectable({
providedIn: 'root'
})
export class LoadingService {
public state: Subject<boolean> = new Subject<boolean>();
}
And the loading stories configuration:
@Injectable({
prividedIn: 'root'
})
class MockLoadingService extends LoadingService {
static instance: MockLoadingService = null;
constructor() {
super();
if (!MockLoadingService.instance) {
MockLoadingService.instance = this;
}
return MockLoadingService.instance;
}
}
@Component({
selector: 'app-loading',
templateUrl: './loading.component.html',
})
class MockLoadingComponent extends LoadingComponent {
constructor(private mockLoadingService: MockLoadingService) {
super(mockLoadingService);
}
}
export default {
title: 'Loading',
component: MockLoadingComponent,
decorators: [
moduleMetadata({
declarations: [MockLoadingComponent],
providers: [MockLoadingService],
}),
],
} as Meta;
export const Loading: Story = props => ({ props });
Loading.play = async () => {
await new Promise(resolve => {
setTimeout(() => {
MockLoadingService.instance.state.next(false);
resolve(null);
}, 2000);
});
};
My question is: Even after running npm run storybook
, the state is updated to false
, but the loading icon in the canvas panel remains visible. How can I ensure that the Angular component is updated correctly with observables or subjects in Storybook?
Additional remarks regarding loading.component.html:
<div *ngIf="state" class="loading" id="loading">
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="25 25 50 50" class="circular">
<circle cx="50" cy="50" r="20" fill="none" class="path"></circle>
</svg>
</div>
Furthermore, the implementation works as expected:
ngOnInit(): void {
this.subscription = this.loadingService.state.subscribe(state => {
this.updateState(state);
console.log(this.state);
});
setTimeout(() => {
this.loadingService.state.next(false);
}, 1000);
}
However, it does not work as intended within the Storybook play function.