Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New Angular renderer throws "Converting circular structure to JSON" when using InjectionToken with options #15333

Closed
rothsandro opened this issue Jun 23, 2021 · 4 comments

Comments

@rothsandro
Copy link

rothsandro commented Jun 23, 2021

Describe the bug
Create an Angular Injection Token that uses the second parameter "options" to pass an object:

export const DEMO_TWO = new InjectionToken('DEMO_TWO', {
    providedIn: 'root',
    factory: () => 'two'
});

Create a story that with moduleMetadata that provides that token (either directly or by importing a module that provides that token):

export default {
  // ...
  decorators: [
    moduleMetadata({
      providers: [
        {
          provide: DEMO_TWO,
          useValue: 'two',
        }
      ]
    })
  ]
} as Meta;

The story shows the following error in the browser:

Converting circular structure to JSON
    --> starting at object with constructor 'InjectionToken'
    |     property 'ɵprov' -> object with constructor 'Object'
    --- property 'token' closes the circle

It works if I

  • set angularLegacyRendering to true OR
  • remove the second argument of the InjectionToken (new InjectionToken('DEMO_TWO'))

To Reproduce
The repo is created with npx sb@next repro
Repo: https://github.com/rothsandro/storybook-injection-token-repro
Relevant files:

  • src/stories/tokens.ts
  • src/stories/Button.stores.ts

I can't deploy it, the build hangs at "info => Output directory: ...".
I created a second repro project without changing anything in the code and directly run the build - same result.

System

  System:
    OS: macOS 10.15.7
    CPU: (12) x64 Intel(R) Core(TM) i7-8750H CPU @ 2.20GHz
  Binaries:
    Node: 12.16.3 - /usr/local/bin/node
    Yarn: 2.4.2 - /usr/local/bin/yarn
    npm: 6.14.4 - /usr/local/bin/npm
  Browsers:
    Chrome: 91.0.4472.114
    Edge: 91.0.864.54
    Firefox: 85.0.1
    Safari: 14.0.2
  npmPackages:
    @storybook/addon-actions: ^6.3.0 => 6.3.0 
    @storybook/addon-docs: ^6.3.0 => 6.3.0 
    @storybook/addon-essentials: ^6.3.0 => 6.3.0 
    @storybook/addon-links: ^6.3.0 => 6.3.0 
    @storybook/angular: ^6.3.0 => 6.3.0 
    @storybook/builder-webpack5: ^6.3.0 => 6.3.0 
    @storybook/manager-webpack5: ^6.3.0 => 6.3.0 

Additional context
We use https://ngneat.github.io/transloco/ for translation which uses such an injection token.

┆Issue is synchronized with this Asana task by Unito

@Marklb
Copy link
Member

Marklb commented Jun 25, 2021

I took a quick look at this, since I already had an idea what may have been happening, and found a fix, but I don't have time to test it right now. Until I have more time to test it, maybe later this afternoon, I will just add what I found here.

The problem seems to be how Angular adds ɵprov to injectable objects. For InjectionToken objects initialized with options the ɵprov.token is it's self.

Storybook's AbstractRenderer and RendererService both use JSON.stringify to create a snapshot of the moduleMetadata that it can use to check if the story should be rendered again. There may be a better solution, but just as a test I used telejson to stringify the metadata and my story seemed to render fine.

The line in AbstractRenderer: https://github.com/storybookjs/storybook/blob/next/app/angular/src/client/preview/angular-beta/AbstractRenderer.ts#L163

@shilman
Copy link
Member

shilman commented Jul 2, 2021

Olé!! I just released https://github.com/storybookjs/storybook/releases/tag/v6.4.0-alpha.11 containing PR #15410 that references this issue. Upgrade today to the @next NPM tag to try it out!

npx sb upgrade --prerelease

Closing this issue. Please re-open if you think there's still more to do.

@shilman shilman closed this as completed Jul 2, 2021
@shilman
Copy link
Member

shilman commented Jul 7, 2021

Boo-yah!! I just released https://github.com/storybookjs/storybook/releases/tag/v6.3.3 containing PR #15410 that references this issue. Upgrade today to the @latest NPM tag to try it out!

npx sb upgrade

@AbhiPanseriya
Copy link

AbhiPanseriya commented Aug 6, 2021

The issue still persists when we pass FormGroup as a args in angular 8 and storybook 6.3.6.
This is how I wrote the story

export default {
    title: 'Custom Textarea Component',
    component: CustomTextareaComponent,
    decorators: [
        moduleMetadata({
            declarations: [CustomTextareaComponent],
            imports: [ReactiveFormsModule],
            providers: [FormBuilder, HttpClient, HttpHandler],
            schemas: [NO_ERRORS_SCHEMA]
        })
    ],
    argTypes: {
        blur: {
            action: 'blur event'
        }
    },
};

const Template = (args: CustomTextareaComponent) => ({
    props: args,
});
//#region Textarea with Value
export const TextAreaWithValue = Template.bind({});
TextAreaWithValue.args = {
    formGroup: new FormGroup({}),
    value: 'lorem ip sum',
};
//#endregion

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants