I have an await
block in my +layout.svelte
for a product fetch
function in the load function.
When the promise is fullfilled it renders a +page.svelte
as a children and I need to pass the product
to that page.
{#await $page.data.productData}
<div class="flex flex-col flex-grow h-64 justify-center items-center">
<Spinner />
</div>
{:then product}
{#key data.pathname}
<div in:fade|global={{ duration: 300 }}>
{@render children?.(product)}
</div>
{/key}
{/await}
in the +page.svelte
that is rendered, how can I access product
?
At the moment I'm using a context but I want to await only one time for the function.
onMount(async () => {
product.set(await $page.data.productData)
});
I have an await
block in my +layout.svelte
for a product fetch
function in the load function.
When the promise is fullfilled it renders a +page.svelte
as a children and I need to pass the product
to that page.
{#await $page.data.productData}
<div class="flex flex-col flex-grow h-64 justify-center items-center">
<Spinner />
</div>
{:then product}
{#key data.pathname}
<div in:fade|global={{ duration: 300 }}>
{@render children?.(product)}
</div>
{/key}
{/await}
in the +page.svelte
that is rendered, how can I access product
?
At the moment I'm using a context but I want to await only one time for the function.
onMount(async () => {
product.set(await $page.data.productData)
});
Share
Improve this question
edited Nov 20, 2024 at 12:31
brunnerh
186k30 gold badges357 silver badges430 bronze badges
asked Nov 20, 2024 at 9:23
FilippoFilippo
1517 bronze badges
1 Answer
Reset to default 0I don't know if this is the best solution, but one solution is that you:
- Create your own context in the layout component that stores
null
- You
await
the context (in the JS part of the layout), and then you store the resolved object in that context - In the HTML-part of the layout, you render the children when the context is not
null
- In the page components you can obtained the resolved object directly through your own context
+layout.server.js
export function load(){
return {
productPromise: getProductPromise(),
}
}
+layout.svelte
<script>
import { onMount, getContext, setContext } from `svelte`
let {
productPromise,
children,
} = $props()
setContext(`product`, null)
onMount(async () => {
setContext(`product`, await productPromise)
})
</script>
{#if getContext(`product`)}
{@render children()}
{:else}
<p>Still loading...</p>
{/if}
/sub-route/+page.svelte
<script>
import { getContext } from `svelte`
let product = $derived(getContext(`product`))
</script>
<p>{JSON.stringify(product)}</p>
But... That does seem like a quite complicated solution IMO ^^' It's not possible for you to await the promise already on the server-side? In its load()
function?