storybook icon indicating copy to clipboard operation
storybook copied to clipboard

Storybook 6.4 with Angular 13 breaks lifecycle hooks of abstract component

Open dkimmich-onventis opened this issue 3 years ago • 15 comments

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.

dkimmich-onventis avatar Nov 30 '21 13:11 dkimmich-onventis

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!

stale[bot] avatar Jan 09 '22 13:01 stale[bot]

This is still an issue...

dkimmich-onventis avatar Jan 10 '22 06:01 dkimmich-onventis

Having this issue as well

f4irline avatar Jan 18 '22 08:01 f4irline

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

fikkatra avatar Jan 18 '22 09:01 fikkatra

Experiencing this issue as well when navigating between stories.

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

jasonhodges avatar Jan 25 '22 16:01 jasonhodges

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

railsstudent avatar Jan 31 '22 13:01 railsstudent

For people experiencing this issue:

  • does the workaround work for you?
  • have you tried the angular builder https://github.com/storybookjs/storybook/blob/next/MIGRATION.md#sb-angular-builder

shilman avatar Jan 31 '22 13:01 shilman

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

dkimmich-onventis avatar Jan 31 '22 13:01 dkimmich-onventis

For people experiencing this issue:

  • does the workaround work for you?
  • have you tried the angular builder https://github.com/storybookjs/storybook/blob/next/MIGRATION.md#sb-angular-builder

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

f4irline avatar Jan 31 '22 14:01 f4irline

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.

ld210 avatar Apr 28 '22 08:04 ld210

Hey @all,

The fix to set angularLegacyRendering to true seems to work

kailo777 avatar Apr 28 '22 11:04 kailo777

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.

dkimmich-onventis avatar May 23 '22 09:05 dkimmich-onventis

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

ld210 avatar Jun 23 '22 08:06 ld210

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()'

impurity-dev avatar Jun 23 '22 15:06 impurity-dev

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.

  • There are no abstract components involved when I get the this.destroyed$.next is not a function error when its called from ngOnDestroy. The component class member declaration looks like private readonly destroyed$ = new Subject<void>();
  • Although the workaround of setting angularLegacyRendering: true fixes this issue, it breaks build-storybook, apparently because it is forcing re-initialization (a.k.a. duplication) of Storybooks DynamicModule when switching between stories (https://github.com/storybookjs/storybook/blob/v6.5.12/app/angular/src/client/preview/angular/helpers.ts#L206), which is causing the following error:
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

nattySP avatar Oct 19 '22 01:10 nattySP

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

SadScream avatar Dec 09 '22 14:12 SadScream