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

[Bug]: Angular APP_INITIALIZER not firing in 7.0.0-beta.48 #21121

Closed
AE1NS opened this issue Feb 16, 2023 · 9 comments · Fixed by #21059
Closed

[Bug]: Angular APP_INITIALIZER not firing in 7.0.0-beta.48 #21121

AE1NS opened this issue Feb 16, 2023 · 9 comments · Fixed by #21059

Comments

@AE1NS
Copy link

AE1NS commented Feb 16, 2023

Describe the bug

When using storybook 7.0.0-beta.48 in angular, the APP_INITIALIZER function is not called before the application is loaded. It seems just to be ignored.

import { moduleMetadata, StoryObj } from '@storybook/angular';
import { Meta } from '@storybook/angular';
import { APP_INITIALIZER } from '@angular/core';

const meta: Meta<ButtonComponent> = {
    component: ButtonComponent,
    decorators: [
        moduleMetadata({
            providers: [
                {
                    provide: APP_INITIALIZER,
                    useFactory: () => {
                        console.log('never called');
                    },
                    multi: true
                }
            ]
        })
    ]
};

To Reproduce

No response

System

No response

Additional context

No response

@mikejpeters
Copy link

Maybe related, I've been having issues with Angular and the v7 beta (tried 7.0.0-beta.43 & 7.0.0-beta.49) where it doesn't seem to initialize modules that are imported using moduleMetadata (I tested that the constructor is never called).

// my-module.ts
@NgModule({})
export class MyModule {
  constructor() {
    console.log('never called');
  }
}

// preview.ts
export const decorators = [
  moduleMetadata({
    imports: [MyModule],
  })
];

@shilman
Copy link
Member

shilman commented Feb 21, 2023

Crikey!! I just released https://github.com/storybookjs/storybook/releases/tag/v7.0.0-beta.52 containing PR #21059 that references this issue. Upgrade today to the @next NPM tag to try it out!

npx sb@next upgrade --prerelease

@AE1NS
Copy link
Author

AE1NS commented Feb 21, 2023

The APP_INITIALIZER is now called when its defined in the story component itself, but when its defined in a module and this module is referenced in moduleMetadata, the APP_INITIALIZER is not called.
I also dont understand where I can set my environment providers.

const meta: Meta<ButtonComponent> = {
    component: ButtonComponent,
    decorators: [
        moduleMetadata({
            imports: [StoryModule]
        })
    ]
};

@NgModule({
    imports: [TranslateModule.forRoot()],
    providers: [
        {
            provide: APP_INITIALIZER,
            useFactory: () => {
                console.log('never called');
            },
            multi: true
        }
    ],
})
export class StoryModule {}

TranslateModule.forRoot() does not seem to provide the TranslateService to my application. The TranslateService is used by some other service dependencies and I always get a ERROR NullInjectorError: R3InjectorError regarding it. In general I would prefer a way to 'hook' in somewhere when the 'base' component of storybook gets created. Thats the place where it should be possible to set environment providers (like the main.ts in an angular project, where the base component gets bootstrapped) (https://angular.io/guide/standalone-components#configuring-dependency-injection). In my example, I have to set the StoryModule inside the moduleMetadata to each Story. But my APP_INITIALIZER should be called for each story everytime.

@mikejpeters
Copy link

@AE1NS have you tried global decorators?

// .storybook/preview.ts

import { Decorator, moduleMetadata } from '@storybook/angular';

export const decorators: Decorator[] = [
  moduleMetadata({
    imports: [...],
    providers: [...],
  }),
];

(I've updated to beta 53, and briefly tried using APP_INITIALIZER this way and it seems to work as expected)

@AE1NS
Copy link
Author

AE1NS commented Feb 22, 2023

@AE1NS have you tried global decorators?

(I've updated to beta 53, and briefly tried using APP_INITIALIZER this way and it seems to work as expected)

Thats exactly what I was looking for, thank you!

Unfortunately I still have the issue here with missing environment providers. As already described, when I import TranslateModule.forRoot(), there is no provider for TranslateService available afterwards.
Example:

import { Decorator, moduleMetadata } from '@storybook/angular';
import { APP_INITIALIZER } from '@angular/core';
import { TranslateModule, TranslateService } from '@ngx-translate/core';

export const decorators: Decorator[] = [
    moduleMetadata({
        imports: [TranslateModule.forRoot()],
        providers: [
            {
                provide: APP_INITIALIZER,
                useFactory: (translateService: TranslateService) => () => {
                    console.log(translateService.instant('TEST'));
                },
                deps: [TranslateService],
                multi: true,
            },
        ],
    }),
];

NullInjectorError: No provider for TranslateService!

@ghost
Copy link

ghost commented Feb 22, 2023

Also running into this issue in 7.0.0-beta.52 when trying to do something similar in preview.js.

@AE1NS
Copy link
Author

AE1NS commented Feb 23, 2023

@valentinpalkovic do you want me to open a new ticket, or will you reopen this one?

@valentinpalkovic
Copy link
Contributor

@AE1NS Yes please :)

@AE1NS
Copy link
Author

AE1NS commented Feb 23, 2023

#21218

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

Successfully merging a pull request may close this issue.

4 participants