#Calling Angular component method from play function? Possible?

1 messages · Page 1 of 1 (latest)

pallid stream
#

Hi everyone! I have a couple of Angular components which don't use inputs but instead they expose public methods to their parents. Is it possible to call these methods from a story? Perhaps in the play function somehow?

reef sluice
#

I am not aware of a good way to do it at the moment. The following is the easiest way I know of to do it, but I don't really recommend it. There are multiple issues with this, such as potential memory issue from a reference to the instance being on a global property, assuming the global reference is updated correctly, and some other rare scenarios that can cause it to not work with more complicated dynamic stories. Listening to various Storybook events, this could be improved to clean up the reference better, but I just don't like having to use the global property reference.

The following relies on a global property being set, which probably stops it from being cleaned up in memory when destroyed and can bleed over into other stories if they don't update the ref also.

So, I don't recommend this, but if you need it then this is the easiest way I know to do it at the moment.

function getStoryComponentInstanceRef(): MyComp {
  const _w: any = window
  return _w._storyCmpInstRef
}

function setStoryComponentInstanceRef() {
  // NOTE: You may need to inject and expose NgZone also, if you need to execute anything inside the zone for change detection.
  function bootstrapped(componentRef: ComponentRef<any>) {
    const _w: any = window
    _w._storyCmpInstRef = componentRef.instance.storyComponentElementRef
  }

  return {
    provide: APP_BOOTSTRAP_LISTENER,
    useValue: bootstrapped,
    multi: true
  }
}

const meta: Meta = {
  component: MyComp,
  decorators: [
    applicationConfig({
      providers: [
        setStoryComponentInstanceRef(),
      ],
    }),
  ],
}

export default meta
type Story = StoryObj<MyComp>

export const Example: Story = {
  play: async ({ canvasElement }) => {
    getStoryComponentInstanceRef().doSomeThing()
  }
}