storybook icon indicating copy to clipboard operation
storybook copied to clipboard

Angular 13 component Input is stringified

Open guillaume-moreau opened this issue 2 years ago • 30 comments

The bug On storybook the Input passed to a component seems to be stringified by some storybook's internal mecanism.

To Reproduce To reproduce the bug I've created a new Angular project with ng new myProject then I add Storybook with npx sb init

I create a component with an Input. I create the associated story.

I can see in my component that the Input is at first an object, but then becomes a string. I've created a repository to reproduce the bug : Repo

The component's code shows the behaviour of this changing Input

System

Environment Info:

  System:
    OS: Windows 10 10.0.19043
    CPU: (4) x64 Intel(R) Core(TM) i5-6200U CPU @ 2.30GHz   
  Binaries:
    Node: 14.17.3 - C:\Program Files\nodejs\node.EXE        
    npm: 6.14.13 - C:\Program Files\nodejs\npm.CMD
  Browsers:
    Chrome: 96.0.4664.93
    Edge: Spartan (44.19041.1266.0), Chromium (96.0.1054.53)
  npmPackages:
    @storybook/addon-actions: ^6.4.9 => 6.4.9 
    @storybook/addon-essentials: ^6.4.9 => 6.4.9 
    @storybook/addon-links: ^6.4.9 => 6.4.9 
    @storybook/angular: ^6.4.9 => 6.4.9 
    @storybook/builder-webpack5: ^6.4.9 => 6.4.9 
    @storybook/manager-webpack5: ^6.4.9 => 6.4.9 

Additional context Please ask me if you have any questions :)

guillaume-moreau avatar Dec 13 '21 15:12 guillaume-moreau

I think it is more than this. After update 6.3.x => 6.4.x in Angular 12.x it stringifies properties which uses initializers in place.

private unsubscribe$: Subject<void> = new Subject<void>();

Becomes a string "new Subject<void>()"

If set value in a constructor then all good:

private unsubscribe$: Subject<void>;
constructor() {
   this.unsubscribe$ = new Subject<void>();
}

I will try to come up with some repro later.

szykov avatar Dec 13 '21 21:12 szykov

Same problem as in #17001

rothsandro avatar Dec 14 '21 06:12 rothsandro

Disabling docs addon fixed the issue for me

module.exports = {
  "stories": [
    "../src/**/*.stories.mdx",
    "../src/**/*.stories.@(js|jsx|ts|tsx)"
  ],
  addons: [{
    name: '@storybook/addon-essentials',
    options: {
      docs: false,
    }
  }]
}

bg-ssh avatar Dec 14 '21 06:12 bg-ssh

Disabling the docs works fine !

Thank you :)

guillaume-moreau avatar Dec 14 '21 08:12 guillaume-moreau

I confirm it too. Disabling docs fix the issue.

szykov avatar Dec 14 '21 09:12 szykov

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 03:01 stale[bot]

bad bot.

jfgreffier avatar Jan 09 '22 16:01 jfgreffier

Does the latest release fix the issue?

rebendajirijr avatar Jan 10 '22 07:01 rebendajirijr

@rebendajirijr No, it doesn't at 6.4.13.

lacolaco avatar Jan 17 '22 06:01 lacolaco

Also not working in 6.5.0-alpha.19

AE1NS avatar Jan 18 '22 13:01 AE1NS

I have been digging around and I am pretty sure the problem originated from this change https://github.com/storybookjs/storybook/commit/9f24a7993b0f10f81d3b1691b17b7b8d0f0d5557#diff-4363e51a0fc41312a0a9ff70bffdcbafe3b027cc494529b2d2a918ae7ef11d3b

I have very little knowledge of the inner working of storybook but what I see here is that and eval that would change the string to a correct type is replaced with an string replacement.

I do not know why that was done and I have not time to test to change it back at the moment so if someone else knows more I wanted to share my findings.

amaino avatar Jan 21 '22 12:01 amaino

I have managed to fix it. Just need to make sure the tests work and figure out how I can push a branch to the repo to create a PR, getting 403 now.

amaino avatar Jan 27 '22 10:01 amaino

We've got the exact same problem which makes our e2e tests literally unusable. A workaround is to create a wrapper component that uses that component but that's massive work.

activenode avatar Mar 23 '22 14:03 activenode

Also the proposed workaround is not really a workaround if you have mdx files as those seem to require the docs. For good reason.

activenode avatar Mar 23 '22 16:03 activenode

Update: Downgrading to @compodoc/[email protected] "fixed" it for us. All other versions broke the application.

So update your package.json to @compodoc/compodoc: "1.1.11"

activenode avatar Mar 24 '22 10:03 activenode

Downgrading to @compodoc/compodoc: "1.1.11" did not work for me, personally. The only fix that seems to work is disabled the docs addon entirely

mrlonis avatar Apr 06 '22 19:04 mrlonis

As per this issue: https://github.com/storybookjs/storybook/issues/16865

I can also confirm removing the component: property from the Story definition also fixes the issue and you don't need to disable the docs addon

mrlonis avatar Apr 19 '22 14:04 mrlonis

Another workaround: "hide" the affected property from compodoc by marking it as private.

rdebeasi avatar Apr 26 '22 18:04 rdebeasi

Another workaround is removing the type from the field, letting Typescript infer it from the initializer, which is recommended by linters anyway:

private unsubscribe$ = new Subject<void>();

yngvebn avatar Apr 27 '22 05:04 yngvebn

Do we have any updates on this?

Benjaminlooi avatar Jul 13 '22 02:07 Benjaminlooi

The best solutions I've seen thus far are to either:

  1. Disable the docs addon

or

  1. Don't set the value in line with the definition. Set the value in the constructor. View this suggestion for more clarification

mrlonis avatar Jul 13 '22 02:07 mrlonis

I'm on Angular 13, storybook 6.5.9. For some reason, I'm not sure if I did something wrong but disabling docs does not work for me

addons: [
    {
      name: '@storybook/addon-essentials',
      options: {
        docs: false, // yes, docs is disabled, but controls are still inferred as string values
      },
    },
    // ...
  ],

and setting the value in the constructor means rewriting components just to get storybook to work.

Benjaminlooi avatar Jul 13 '22 02:07 Benjaminlooi

Hmm, I'm sorry to hear none of the solutions worked. Hopefully we get an update or resolution to this issue someday

mrlonis avatar Jul 13 '22 02:07 mrlonis

Fyi: My workaround is adding @internal jsdoc annotation on component properties that occur the error and configure compodoc with disableInternal: true.

lacolaco avatar Jul 13 '22 02:07 lacolaco

Current releases (6.5.*) for Angular are completely broken. It stringifies everything. Disabling docs is not helping anymore.

szykov avatar Jul 13 '22 07:07 szykov

I'm also facing this issue. My current workaround is by adding @ignore on top of the method/property.

stirelli avatar Jul 20 '22 10:07 stirelli

push... Would be nice if this got fixed quickly. current workaround for me is to exclude all properties which ends with a $ (subjects)

in preview.js

  controls: {
    exclude: /(.+)\$$/
  }

since the error also occurs with number properties, i followed the advice on this thread and enabled the legacyRendering. Works for me.

rbeier avatar Jul 28 '22 09:07 rbeier

So frustrating...

IslombekHasan avatar Aug 15 '22 19:08 IslombekHasan

I am encountering this issue as well with Angular 13 and Storybook 6.5. Would love to see it resolved as I see Storybook as a potentially valuable tool for my organization!

Disabling docs does not resolve

bethlym avatar Aug 30 '22 16:08 bethlym

I have a similar issue. But it's not only inputs but also all property of my component with a default value.

MarkB, from the storybook discord, pointed me that compodoc was responsible of wrong analysis of the component and it was stringifying default values.

I dig it a bit and indeed, all default values were stringified directly in the documentation.json generated by compodoc which is created right before storybook launch.

I found a workaround, it's really not ideal:

In preview.js, I added:

import docJson from '../documentation.json';

const allFields = docJson.components
  ?.map(c => ([...(c.propertiesClass || []), ...(c.inputsClass || [])]))
  .flat();

allFields.forEach(p => {
  if (p.type === 'number') {
    p.defaultValue = +(p.defaultValue);
  } else {
    delete p.defaultValue;
  }
});

setCompodocJson(docJson);

By deleting default values, storybook won't overwrite them with stringified values. It's also possible de eval array and object but I prefer avoid eval...

At least components are workings but it's harder to overwrite values manually directly in storybook.

MarkB said, he was working on new version of @storybook/angular that might fix some issues. And an other colleague said he had no problems with storybook inside a nx project, if I have some times, I will investigate it too.

I hope it will help someone! Have a nice day

asirko avatar Sep 20 '22 07:09 asirko