Reputation: 3580
I want to use Storybook to develop and test my UI components and release them as npm library from within the same project. This is why I encapsulate all components as a single feature module. I wanted to create a simple module which generates a form and allows some undo functionality. My problem is that Storybook cannot inject the Formbuilder Service into my component.
My setup is as follows:
The story:
storiesOf('UndoForm', module)
.addDecorator(
moduleMetadata({
imports: [ReactiveFormsModule, UndoFormModule]
}),
)
.add('Testform', () => ({
template: '<mods-undo-form></mods-undo-form>'
})
);
The UndoFormModule:
@NgModule({
declarations: [UndoFormComponent],
imports: [ReactiveFormsModule],
exports: [UndoFormComponent]
})
export class UndoFormModule {}
The UndoFormComponent:
@Component({
selector: 'mods-undo-form',
templateUrl: './undo-form.component.html',
styleUrls: ['./undo-form.component.scss']
})
export class UndoFormComponent implements OnInit {
[...]
constructor(private fb: FormBuilder) { }
[...]
}
The error I get is:
Can't resolve all parameters for UndoFormComponent: (?).
What I found out is, that when I use the @Inject
annotation explicitly, then the code works:
constructor(@Inject(FormBuilder) private fb: FormBuilder) { }
Is there any possibility to prevent the usage of the explicit annotation?
Upvotes: 8
Views: 13323
Reputation: 3576
You can import it directly into the story. like so:
import { BannerV2Component } from './banner.v2.component';
import { moduleMetadata } from '@storybook/angular';
export default {
title: 'Banner',
decorators: [
moduleMetadata({
imports: [ReactiveFormsModule, UndoFormModule],
providers: [FormBuilder],
})
]
}
export const OptionOne = () => ({
component: BannerV2Component,
props: {
mainText:'Text Two',
showBreadcrumbs:true,
},
});
Upvotes: 2
Reputation: 211
You need to add "emitDecoratorMetadata": true
in compilerOptions
object in .storybook/tsconfig.json
file.
So your .storybook/tsconfig.json
should be like this:
{
"extends": "../tsconfig.app.json",
"compilerOptions": {
"emitDecoratorMetadata": true, <--------- Add this!
...
},
...
}
Then make sure to restart your storybook process.
Upvotes: 13
Reputation: 370
You need to provide 'FormBuilder' in the providers array in moduleMetadata of the storybook decorator. This way, your storybook setup will recognise that FormBuilder is being used as an injectable dependency in your component.
Here is how I am using it in one of our stories:
storiesOf('UndoForm', module)
.addDecorator(
moduleMetadata({
imports: [ReactiveFormsModule, UndoFormModule],
providers: [FormBuilder],
}),
)
.add('Testform', () => ({
template: '<mods-undo-form></mods-undo-form>'
})
);
Upvotes: 0