My brain exploded and i got a cool idea for a global component to handle the behavior of API data loading in my app.
I created a component that handle the transition between the loader, the content (a slot) and the error message if the loading failed.
However I am running into an issue, this works perfectly when just putting text in the slot, but the main objecting of fetching an API is to use the data right?
My issue is simple: I have no idea of how I could access the component data (it contains the data from api response) inside my slot.
It will be easier with code so:
My component looks like this:
<ContentLoader v-if="loading" :mode="loaderMode" />
<div v-else-if="error" class="error-mod">
<h1 class="uB" style="margin-left:10px">Unable to get {{errorName}}.</h1>
<p class="uL" style="margin-left:10px">{{errorDescription}}</p>
<p class="uL tw text-center" style="opacity:0.4">{{errorMessage}}</p>
<button class="error-btn uB tw" @click="fetchAPI(url)">Retry</button>
</div>
<slot v-else />
The content will be in the <slot />
so when I want to use it I need to do this:
<ApiLoader url="url/to/the/api">
Hello world!
</ApiLoader>
This will fetch something from the api and then display the hellow orld, but this isn't the wanted behavior let's say I need to do this:
<ApiLoader url="url/to/the/api">
<div v-for="item in data" :key="item">
Found {{item}} in stuff we loaded idk
</div>
</ApiLoader>
And that will cause problems as data
when called in the parent is not defined here, but inside the ApiLoader
component.
What I need to do is access data
inside the component, I tough of using emit
but I don't really see how I could implement it easely since I haven't used them quite often.
Thanks for reading! (and ty also if you answer)
After searching trough the docs of $emit
I found a cool way, it's just kinda sad it require a variable in the parent component,
basically defined a variable like apiData
and then simply done this :
<ApiLoader
:url="url"
@dataLoad="(data) => apiData[dataName] = data">
<div class="tw uL">{{apiData[dataName]}}</div>
</ApiLoader>
This will simply load the data to a parent variable (apiData[dataName]
where dataName
is another var) so it's usable in the parent component
ANd in the component that loads api stuff I just use this.$emit("dataLoad", data)
and boom fixed.
Actually using emit is really easy and powerful, but keep in mind that for my case i have an async request handler that emit only when the data is loaded, and the content inside my slot
is rendered only when that data is loaded (so if you do something similar and render the content without that kind of handling be careful to verify the integrity of the data you use to create your stuff)