storybookjs / storybook

Storybook is the industry standard workshop for building, documenting, and testing UI components in isolation
https://storybook.js.org
MIT License
83.49k stars 9.13k forks source link

Storybook 6.4 with Angular 13 breaks lifecycle hooks of abstract component #16838

Open dkimmich-onventis opened 2 years ago

dkimmich-onventis commented 2 years ago

Describe the bug In my Angular 13 project using Storybook 6.4, I am using an abstract component to destroy Observables. There I provide a subject, and in ngOnDestroy() that subject is completed. Since Storybook 6.4, I am getting a runtime error in those stories where I use that abstract component:

this.destroy$.next is not a function

It seems like the subject is already destroyed.

To Reproduce https://github.com/dsimon-onventis/storybook-lifecycle-errors-repro

Open one of the "Button" stories, and then navigate to another story.

System Environment Info:

System: OS: Linux 5.10 Ubuntu 20.04.3 LTS (Focal Fossa) CPU: (8) x64 Intel(R) Core(TM) i5-8365U CPU @ 1.60GHz Binaries: Node: 14.18.1 - /usr/local/bin/node Yarn: 3.1.1 - /usr/bin/yarn npm: 8.1.4 - ~/.npm-global/bin/npm Browsers: Chrome: 96.0.4664.45 npmPackages: @storybook/addon-actions: ^6.4.1 => 6.4.1 @storybook/addon-docs: ^6.4.1 => 6.4.1 @storybook/addon-essentials: ^6.4.1 => 6.4.1 @storybook/addon-links: ^6.4.1 => 6.4.1 @storybook/angular: ^6.4.1 => 6.4.1 @storybook/builder-webpack5: ^6.4.1 => 6.4.1 @storybook/manager-webpack5: ^6.4.1 => 6.4.1

Additional context With angularLegacyRendering set to true, there are no runtime errors.

stale[bot] commented 2 years ago

Hi everyone! Seems like there hasn't been much going on in this issue lately. If there are still questions, comments, or bugs, please feel free to continue the discussion. Unfortunately, we don't have time to get to every issue. We are always open to contributions so please send us a pull request if you would like to help. Inactive issues will be closed after 30 days. Thanks!

dkimmich-onventis commented 2 years ago

This is still an issue...

f4irline commented 2 years ago

Having this issue as well

fikkatra commented 2 years ago

Having the same issue. In my case, it's not ngDestroy, but ngAfterViewInit. This lifecycle hook code:

private sizeChangedSubject = new Subject<void>();

public ngAfterViewInit(): void {
  setTimeout(() => {
    this.sizeChangedSubject.next();
  }, 0);
}

produces the error:

ERROR TypeError: this.sizeChangedSubject.next is not a function

jasonhodges commented 2 years ago

Experiencing this issue as well when navigating between stories.

this.destroy$.next is not a function. ngOnDestroy() { this.destroy$.next(); this.destroy$.complete(); }

railsstudent commented 2 years ago

I have this issue and cannot upgrade to latest version of storybook

shilman commented 2 years ago

For people experiencing this issue:

dkimmich-onventis commented 2 years ago

I'm already using the angular builder, same issue. For me, the workaround works.

f4irline commented 2 years ago

For people experiencing this issue:

I'm using the Angular builder as well. The workaround works but for some reason breaks other stuff, like changes in @Input() values not being reflected in the Storybook UI

ld210 commented 2 years ago

This is still an issue with Storybook 6.4.22 and Angular 13.3. Workaround looks to be working (and i am using the angular builder), but i haven't yet tested all stories.

kailo777 commented 2 years ago

Hey @all,

The fix to set angularLegacyRendering to true seems to work

dkimmich-onventis commented 2 years ago

In my real project the error is gone after updating to Storybook 6.5, however in the reproduction repo the error still appears. Can't tell why, will keep you updated.

ld210 commented 2 years ago

Issue is still there with 6.5, if i remove "angularLegacyRendering", the OnDestroy hook breaks storybook.

impurity-dev commented 2 years ago

I was able to bypass this issue by initializing the destroy subject in the constructor. When it was initialized as your example has it, it gets set to a string of its initialization. i.e. onDestroy = 'new Subject()'

nattySP commented 1 year ago

I am having this problem as well. @storybook/angular v6.5.12 (also tried v6.5.13) @angular v13.3.11 I am using the builder.

StorybookModule.js:33 Unhandled Promise rejection: Type AppComponent is part of the declarations of 2 modules: DynamicModule and DynamicModule! Please consider moving AppComponent to a higher module that imports DynamicModule and DynamicModule. You can also create a new NgModule that exports and includes AppComponent then import that NgModule in DynamicModule and DynamicModule. ; Zone: <root> ; Task: Promise.then ; Value: Error: Type AppComponent is part of the declarations of 2 modules: DynamicModule and DynamicModule! Please consider moving AppComponent to a higher module that imports DynamicModule and DynamicModule. You can also create a new NgModule that exports and includes AppComponent then import that NgModule in DynamicModule and DynamicModule.
    at verifySemanticsOfNgModuleDef (StorybookModule.js:33:1)
    at DynamicModule.get (StorybookModule.js:33:1)
    at getInjectorDef (StorybookModule.js:33:1)
    at R3Injector.processInjectorType (StorybookModule.js:33:1)
    at StorybookModule.js:33:1
    at StorybookModule.js:33:1
    at Array.forEach (<anonymous>)
    at deepForEach (StorybookModule.js:33:1)
    at new R3Injector (StorybookModule.js:33:1)
    at createInjectorWithoutInjectorInstances (StorybookModule.js:33:1)

The AppComponent in question is https://github.com/storybookjs/storybook/blob/v6.5.12/app/angular/src/client/preview/angular/components/app.component.ts

SadScream commented 1 year ago

The problem is in the Compodoc library. Add comment @ignore on the property that is converted to a string by mistake and the problem will disappear. e.g.

  /**
   * @ignore
   */
  usefulProperty = {};

Also you can try this