kit icon indicating copy to clipboard operation
kit copied to clipboard

await parent() causes parent layout load to re-run

Open hyunbinseo opened this issue 2 years ago • 2 comments

Describe the bug

According to the loading data documentation,

To summarize, a load function will re-run in the following situations:

  • It calls await parent() and a parent load function re-ran

A child load function that calls await parent() should not cause parent load function(s) to re-run.

It is the other way around - the child load function should re-run if the parent load function re-ran.

However, calling await parent() seems to cause the parent load function(s) to re-run.

Reproduction

Steps

  1. Open the StackBlitz project.
  2. Alternately click veritas and lacetti links.
  3. Check the console.

Logs

/routes/[sedan]/[id]/+layout.server.ts
/routes/[sedan]/[veritas]/+layout.server.ts

/routes/[sedan]/[lacetti]/+layout.server.ts
/routes/[sedan]/[id]/+layout.server.ts # not expected

/routes/[sedan]/[veritas]/+layout.server.ts
/routes/[sedan]/[id]/+layout.server.ts # not expected

Switching between /sedan/veritas and /sedan/lacetti should not cause the following function to re-run.

/** @type {import('./$types').LayoutServerLoad} */
export async function load({ params: { type } }) {
  console.log(`/routes/[${type}]/[id]/+layout.server.ts`);
  return {};
}

It should re-run only if the params.type has changed. It has not. The value stays as sedan.


Fix

  1. Remove await parent(); from /routes/[type]/[id]/+layout.server.ts
  2. Alternately click veritas and lacetti links.
  3. Check the console.

Logs

/routes/[sedan]/[id]/+layout.server.ts
/routes/[sedan]/[veritas]/+layout.server.ts

/routes/[sedan]/[lacetti]/+layout.server.ts

/routes/[sedan]/[veritas]/+layout.server.ts

Logs

No response

System Info

❯ npm list
├─ @sveltejs/[email protected]
├─ @sveltejs/[email protected]
├─ @sveltejs/[email protected]
├─ [email protected]
├─ [email protected]
└─ [email protected]

Severity

annoyance

Additional Information

No response

hyunbinseo avatar Jan 18 '23 01:01 hyunbinseo

Giving this the documentation because this works as designed. If you are using await parent() in a server load function, that parent data needs to be made available somehow, and passing the data back to the server would not scale for larger payloads. Since the server is stateless, the parent load function needs to rerun in order to make that data available.

dummdidumm avatar Jan 18 '23 09:01 dummdidumm

I have a similar issue, but with client loads.

From a childs load function, I'm calling await parent() and then throwing a redirect. This causes the parent load to be called twice. The reason for the redirect is to automatically select a child route ie: go from /foo/ to /foo/bar

The parent load calls a slow API so I'd like to avoid that.

Is this intended, if so what is a better way to load a list of data and then automatically select the first one AND change the route accordingly? Thanks!

osmanlodzero avatar Jun 12 '23 11:06 osmanlodzero