angularstorybookangular12angular-upgradeangular-storybook

Angular 12 Storybook 'this' context transform fields to string


I updated lib project from 11 to 12 angular version. Updated storybook from 6.1 to 6.4. Build builds well, without errors. Storybook compiles as well, BUT... I received strange errors.

Error: compareWith must be a function

TypeError: this.onChange is not a function

But in component class it is declared.

onChange = (value: any) => {};

The same with compareWith, it declares as @Input() compareWith: (o1: T, o2: T) => boolean = ((o1: T, o2: T) => o1 === o2);

It worked good with 11 angular and 6.1 storybook. I started debugging and found this (I logged component context)

clearable: true
compareWith: "((o1: T, o2: T) => o1 === o2)"
disabled: false
id: "select"
labelParamName: "name"
lastScrollTop: NaN
list: (13) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}]
matSelect: MatSelect {_elementRef: ElementRef, _defaultErrorStateMatcher: ErrorStateMatcher, _parentForm: NgForm, _parentFormGroup: null, ngControl: NgModel, …}
multiple: true
ngModelControl: undefined
onChange: "() => {...}"
onTouched: "() => {...}"

It casts functions to string

I tried to find similar questions, but I didn't find. Tried to update angular and storybook from the beginning, but nothing. I followed link: Angular update Storybook update Storybook migration


Solution

  • I have recently encountered the same TypeError: this.onChange is not a function problem (Angular 13, Storybook 6.5.3).

    Searching for a solution, I came across this issue: https://github.com/storybookjs/storybook/issues/17004. As suggested there, downgrading to @compodoc/compodoc@1.1.11 seemed at first to help; however, it soon turned out that other fields get stringified as well: e.g. public instance property innerControl = new FormControl('') became "new FormControl('')" (as string) and threw errors, of course. In this case, assigning the value in the constructor works; yet, it might not always be what we want.

    So as long as we don't have a fixed version of Compodoc, a possible solution is to disable docs on the story level:

    export default {
        title: 'Components/Inputs/TextInput',
        component: MyCustomTextInputComponent,
        parameters: {
            docs: false,
        },
        ...
    }
    

    You might, of course, disable docs completely in .storybook/main.js, but then you can't have .mdx documentation, either. On the other hand, if docs are disabled only for the given component's stories, you can still add an .mdx file and the stories will work as well.