createAsync unexpected behaviour when accessing route through URL, rather than within the app

https://codesandbox.io/p/devbox/pedantic-sea-9z2f4g I have an async function which makes a network request to retrieve some data from the backend. However, it seems as if the network request isn't made (but it is, I've confirmed). When I access the URL directly from the address-bar, a request is made to the backend, response is received but the UI doesn't behave as expected. All works as expected if I access the URL from within the app, e.g by clicking a button that uses navigate(). In the sandbox, an error message should show up in the page - when directly entering the URL in the address bar. This doesn't happen, unless the URL is accessed from within the app, using the link "book" at the top. Why is that happening?
No description
No description
4 Replies
Mr Void
Mr VoidOP7d ago
accessing the URL within the app: shows the expected error msg accessing the URL directly through address-bar: doesn't show the error as expected
Madaxen86
Madaxen867d ago
That's  expected behavior. You can't use a signal setter inside createAsync because with SSR it runs on the server and the signal will be sent to the client with the default value. Two options: 1. throw the error inside the asyncDataFetch and use a ErrorBoundary to show a fallback
<Suspense fallback={<span>Loading ...</span>}>
<ErrorBoundary
fallback={
(err,reset) => (
<button onClick={() => reset()}>There was an error: {err()} - click to retry</span>
)
}>
<span>data: {data()}</span>
</Show>
</ErrorBoundary>
<Suspense fallback={<span>Loading ...</span>}>
<ErrorBoundary
fallback={
(err,reset) => (
<button onClick={() => reset()}>There was an error: {err()} - click to retry</span>
)
}>
<span>data: {data()}</span>
</Show>
</ErrorBoundary>
2. keep the asyncDataFetch as is and use change JSX like e.g.
const data = createAsync(async () => await asyncDataFetch());

return (
<div class="">
<Suspense fallback={<span>Loading ...</span>}>
<Show when={!data()?.err}>
fallback={
<span>There was an error: {data()?.error}</span>
}>
<span>data: {data()}</span>
</Show>
</Suspense>
</div>
);
const data = createAsync(async () => await asyncDataFetch());

return (
<div class="">
<Suspense fallback={<span>Loading ...</span>}>
<Show when={!data()?.err}>
fallback={
<span>There was an error: {data()?.error}</span>
}>
<span>data: {data()}</span>
</Show>
</Suspense>
</div>
);
Mr Void
Mr VoidOP7d ago
how do I not use SSR? is that a default setting for only createAsync?
Madaxen86
Madaxen867d ago
SSR is defined in the app.config.ts You can set SSR: false to have a SPA with pure client side rendering But again setting state inside another signal (which createAsync is under the hood is not a good pattern.

Did you find this page helpful?