typing Page props ?
is it possible to type the props for the page? I'm tryna to block the page until render, and the best I've come up with is:
but the props have to be manually typed
22 Replies
RouteSectionProps
But when the server function is cached you don’t need to pass a initial value because the client will get it from the cache when it’s already preloaded.
But the signal is possibly undefined which I’m trying to avoid
As it is async data it may be undefined as createAsync does not await.
And if ssr is enabled the server might start rendering will start streaming before the promise has resolved.
That’s why we can add suspense boundaries which will render a fallback on initial load .
But there’s a few things you can do depending on what you want to do.
First you can add deferStream:true to createAsync which will prevent streaming until the promise is resolved. Unfortunately typescript won’t pick this up.
So you can also add a Show component with keyed prop which will help typescript to narrow the type to the actual resolved type of the promise.
Hmm yea I have deferStream here
I guess I could just cast the return value to be ignore the
| undefined
. I don't really want to introduce extra markup when i know the value will be defined
two things:
- is there a reason TS doesn't pick up on the deferStream
?
- anything wrong with making something like this for this case:
That way it's always defined? Is there a case I'm not considering?I‘m not deep into the source code of solid.
My best guess:
Streaming only happens when the server renders the page (directly hit the url or refresh browser) that’s when defer happens.
But on client side navigation the signal will still be undefined until resolved
deferStream
stops the SSR response reaching the client until the data has loaded, but it doesn't stop the non-blocking nature of solid's async handling
The route's JSX will be rendered while the data is still loading, and then (with deferStream
) the server wll update the places that used the data to have the new values, and then send that result to the client
The wrong thing with your createAsyncDeferred
is that it's a lie - selections
will be undefined on the server initially, you can account for that with <Show>
to type narrow and remove the undefined
, or do optional chaining like selections()?.value
So it will only render the fallback ever on server if I use deferStream, essentially ?
Pretty much, the server will only respond once the data is in place
Interesting
So if I do my helper thing, realistically nothing can come of this right? TS is not runtime so even if on server first pass there’s some broken markup, it will never reach client until it’s accurate (at which point forcing the signal to be defined is accurate)?
Like I get that it’s semantically incorrect bc on server at some point that will be undefined
TS isn’t runtime but what it’s telling you is important, on the server the value will initially be undefined, and if you don’t respect that then you could end up with ‘cannot access property of undefined’ on the server
deferStream pauses the response from being sent but the JSX will still fully evaluate, so you need appropriate guards in place for the undefined case
Ok true
If you use Show so that there’s 0 markup initially that’s fine, since when the response is sent it would have re-evaluated the Show
Yea I guess im trying to force a way of writing code into this that just isn’t really possible
I just switched off of Astro and so I’m trying to copy like 1:1 over but it’s not matching up different paradigm
Fwiw this sort of stuff is what solid 2.0 is looking to address, but for now we just have to live with guarding against undefined with async data
Ok cool. I feel like a lot of these things are either a. Missing docs or b. Really primitive and missing sensible abstractions
That’s the nature of adopting it this early I suppose though
Do you mean the specific options like deferStream or the bigger picture of loading async data and pleasing typescript?
Just like the patterns around these things
Like here I have to define like 3 separate functions to get ssr’d data going, as opposed to remix/svelte/old next where I dump everything into an exported function and I have it
Also more complex examples would be cool. I have no clue if I’m doing things properly rn
tbf the route preloader isn’t mandatory but I get your point haha
Maybe it’s just a docs thing then
I think having everything in one docs is awesome, but also is confusing a lot when it’s jumping me between router and start
But I thought that I needed the load/preload for it to work based on docs
Yeah it’s tricky since technically none of what we’ve discussed has to do with Start but a lot of it gets demoed there
Just the file based routing syntax
Right right
I’ll just start looking at source code to figure things out instead lol
I have to agree.
createAsync is part of the router doc which has only this as an example
While a more sophisticated example can only be found in the solid-start docs for data loading.
But there’s no example showing how to fetch data and also do the mutation/ revalidation of cached functions which just gives a whole picture of how to do it the solid way.