storybookjs / storybook

Storybook is the industry standard workshop for building, documenting, and testing UI components in isolation
https://storybook.js.org
MIT License
84.25k stars 9.26k forks source link

Using Loaders to fetch API data in storybook/vue #14770

Open epiknut opened 3 years ago

epiknut commented 3 years ago

What's the problem? I'm trying to fetch API data by using the experimental feature "Loaders" in storybook/vue. Everything works fine with the request itself, but I can't figure out how to get or use the "loaded" data. I'm aware that I haven't included the loaded data in the "Template" below, but I have tried a lot of things without getting it to work properly. So I thought I'd check in here for some pointers before my brain melts.

The end goal here is to use the requested data in both a story and an addon. In my addon I'm using the api.getCurrentStoryData() function to list all available data for the current story, but the loaded data does not seem to be available.

This is my code:

import Page from './Page.vue';

export default {
  title: 'Page',
};

const Template = (args, { argTypes, loaded: { mydata} }) => ({
  components: { Page },
  props: Object.keys(argTypes),
  template: '<page v-bind="$props" />',
});

export const Default = Template.bind({});
Default.args = { ... }
Default.loaders = [
  async () => ({
    mydata: (await fetch('https://jsonplaceholder.typicode.com/todos/1')).json(),
  }),
];

Is there documentation on this? There exists documentation for react, but not vue. The react docs are here: https://storybook.js.org/docs/react/writing-stories/loaders

jonniebigodes commented 3 years ago

@epiknut thanks for bringing this to our attention. And indeed you're right. The loaders are still experimental and subject to changes at any time. I didn't adjust the documentation yet because there are still some nuances to it on my end that I need to further test. Once I've managed to get this working properly I'll adjust the docs/snippets.

Stay safe

epiknut commented 3 years ago

@jonniebigodes Got it, thanks for the reply :)

BennaceurHichem commented 3 years ago

Any Updates about this issue, the same issue for me, I even tried to set global loaders then use them in my stories using loaded.mydata like mentioned in the doc that it's accessible for all stories, the problem is that I couldn't get this data and pass it into my story component property, even if the request handled in the loader is handled correctly, thanks for letting us now the improvement in this issue

jonniebigodes commented 3 years ago

@BennaceurHichem I have a working reproduction here for vue 3, one for Angular here, and svelte here. Vue 2 is a bit of an edge case that I'm still working on. Hence why I haven't pushed the updated docs for the other frameworks. As I wanted to update this to all of them.

csaszika commented 1 year ago

@jonniebigodes do you have an example with storybook 7 too perhaps? I copied everyhing, but my StoryContext is always undefined.

preview.js

export const loaders = [
  async () => ({
    myData: await (await fetch(`http://localhost:4400/scss/xxx.scss`)).text(),
  }),
];

X.stories.ts

export const DefaultStyle: StoryFn<MyComponent> = (args: MyComponent, { loaded: { myData }}) => ({
  props: args,
  template: `
<div class="whf-game-card-container">
    <whf-game-card [game]="game" [jackpot]="jackpot">
    </whf-game-card>
</div>
  `,
  extraThing: myData,
});