S
SolidJS3mo ago
klequis

How to use load property of <Route>

I haven't been able to figure out how to use <Route>'s load function and haven't found a complete example. One property of props in Person has the data from the fetch but it is still a promise. I'm not sure if it should be and if so, what to do with it. index.jsx
import { lazy } from "solid-js";
import { render } from "solid-js/web";
import { Router, Route } from "@solidjs/router";
import { loadPerson } from "./route.data";

const Person = lazy(() => import("./pages/Person"))
const Home = lazy(() => import("./pages/Home"))

render(() => (
<Router>
<Route path="/" component={Home} />
<Route
path="/person"
load={loadPerson}
component={Person}
/>

</Router>
), document.getElementById("root"));
import { lazy } from "solid-js";
import { render } from "solid-js/web";
import { Router, Route } from "@solidjs/router";
import { loadPerson } from "./route.data";

const Person = lazy(() => import("./pages/Person"))
const Home = lazy(() => import("./pages/Home"))

render(() => (
<Router>
<Route path="/" component={Home} />
<Route
path="/person"
load={loadPerson}
component={Person}
/>

</Router>
), document.getElementById("root"));
route.data.js
import { cache } from "@solidjs/router";

async function fetchPerson() {
const a = await fetch(`https://swapi.tech/api/people/1/`);
const b = await a.json();
console.log("b", b);
return b;
}

export const loadPerson = cache(async () => {
const [person] = createResource(() => "", fetchPerson);
return person;
}, "getUserKey");
import { cache } from "@solidjs/router";

async function fetchPerson() {
const a = await fetch(`https://swapi.tech/api/people/1/`);
const b = await a.json();
console.log("b", b);
return b;
}

export const loadPerson = cache(async () => {
const [person] = createResource(() => "", fetchPerson);
return person;
}, "getUserKey");
Person.jsx
import { createSignal, createResource } from "solid-js";

export default function Person(props) {
// do I use createResource again?
const [user] = createResource("", peops.data); // doesn't work

return (
<>
<input
type="number"
min="1"
placeholder="Enter Numeric Id"
onInput={(e) => setUserId(e.currentTarget.value)}
/>
<span>{user.loading && "Loading..."}</span>
<div>
<pre>{JSON.stringify(user(), null, 2)}</pre>
</div>
</>
);
};
import { createSignal, createResource } from "solid-js";

export default function Person(props) {
// do I use createResource again?
const [user] = createResource("", peops.data); // doesn't work

return (
<>
<input
type="number"
min="1"
placeholder="Enter Numeric Id"
onInput={(e) => setUserId(e.currentTarget.value)}
/>
<span>{user.loading && "Loading..."}</span>
<div>
<pre>{JSON.stringify(user(), null, 2)}</pre>
</div>
</>
);
};
11 Replies
klequis
klequis3mo ago
This works but const person = createAsync(() => getPerson(props.params.id)); in Person seems to be redundant. Is it correct?
import { lazy } from "solid-js";
import { render } from "solid-js/web";
import { Router, Route, createAsync } from "@solidjs/router";
import { cache } from "@solidjs/router";

const getPerson = cache(async (id) => {
return (await fetch(`https://swapi.tech/api/people/${id}/`)).json()
}, "getPerson")

const Home = lazy(() => import("./pages/Home"))

function loadPerson({params, location}) {
void getPerson(params.id)
}

render(() => (
<Router>
<Route path="/" component={Home} />
<Route
path="/person/:id"
component={Person}
load={loadPerson}
/>
</Router>
), document.getElementById("root"));

function Person(props) {
const person = createAsync(() => getPerson(props.params.id));

return (
<>
<h1>Person</h1>
<div>
<pre>{JSON.stringify(person(), null, 2)}</pre>
</div>
</>
)
}
import { lazy } from "solid-js";
import { render } from "solid-js/web";
import { Router, Route, createAsync } from "@solidjs/router";
import { cache } from "@solidjs/router";

const getPerson = cache(async (id) => {
return (await fetch(`https://swapi.tech/api/people/${id}/`)).json()
}, "getPerson")

const Home = lazy(() => import("./pages/Home"))

function loadPerson({params, location}) {
void getPerson(params.id)
}

render(() => (
<Router>
<Route path="/" component={Home} />
<Route
path="/person/:id"
component={Person}
load={loadPerson}
/>
</Router>
), document.getElementById("root"));

function Person(props) {
const person = createAsync(() => getPerson(props.params.id));

return (
<>
<h1>Person</h1>
<div>
<pre>{JSON.stringify(person(), null, 2)}</pre>
</div>
</>
)
}
peerreynders
peerreynders3mo ago
This reflects my understanding. The return type of cache() is identical to the return type of the wrapped function; so it will return a promise (i.e. is async) if the wrapped function returns one. createAsync() converts a promise (async) to a signal (i.e. it creates an async-to-reactive boundary). The resulting signal can then be used in JSX and be expected to reactively update. This is handy when you revalidate, as the wrapped function is re-run to produce an entirely new promise that once resolved has its value placed on the signal created by createAsync(). https://docs.solidjs.com/reference/solid-router/data-apis/cache#:~:text=The%20cache%20can,from%20the%20actions.
klequis
klequis3mo ago
Helps improve my understanding. Thanks!
peerreynders
peerreynders3mo ago
1. The “documentation” you were looking for was here https://github.com/solidjs/solid-router?tab=readme-ov-file#data-functions--useroutedata 2. Based on your code I put together a working StackBlitz example: https://stackblitz.com/edit/solidjs-templates-h7n8dj 3. The Data API (cache/createAsync) is considered an alternative to "Load Functions" https://github.com/solidjs/solid-router?tab=readme-ov-file#data-apis 4. Use either createResource OR cache/createAsync BUT not both. cache cannot be used on createResource. Come SolidJS 2.0 cache/createAsync will be the preferred approach. createResource turned out to be not primitive enough so it was broken into cache() and createAsync()
peerreynders
StackBlitz
solidjs/router old Load Functions API demo - StackBlitz
A Solid TypeScript project based on @solidjs/router, solid-js, typescript, vite and vite-plugin-solid
GitHub
GitHub - solidjs/solid-router: A universal router for Solid inspire...
A universal router for Solid inspired by Ember and React Router - solidjs/solid-router
peerreynders
peerreynders3mo ago
Same demo; this time with cache/createAsync instead https://stackblitz.com/edit/solidjs-templates-vgam8k
peerreynders
StackBlitz
solidjs/router new Data API demo - StackBlitz
A Solid TypeScript project based on @solidjs/router, solid-js, typescript, vite and vite-plugin-solid
klequis
klequis3mo ago
I have since created two examples. I couldn't get them working on StackBlitz so here they are in github: https://github.com/klequis/solid-router-load-functions I find your first example (solidjs-templates-h7n8dj) interesting in the way it differs from my example02 in the above repo. You - modified the response in fetchPerson returning only name, - then use createResource in loadPerson. - but don't need createAsync in <Person> I did neither but did need createAsync in [id].jsx (formally Person.jsx).
I also followed "A common pattern" example from this section of the router README Thank you for your efforts. They have been very educational. I just noticed that your solution using createResource in the load function is listed in the Migration from v0.9.x doc and it suggests that was the way to do it before 10.x
peerreynders
peerreynders3mo ago
The pattern in SolidJS 2.0 is moving towards bypassing the Route load property entirely, relying entirely on cache() to dedup requests.
klequis
klequis3mo ago
I was searching far and wide for examples of using the load function and found next to nothing. Perhaps it was never very popular.
peerreynders
peerreynders3mo ago
useRouteData has been a thing with SolidStart Beta 1, but the thinking has changed drastically with Beta 2. https://hackmd.io/@0u1u3zEAQAO0iYWVAStEvw/rkRVTcTWp
HackMD
Router Data APIs - HackMD
Potential Router APIs for data
Carlo Nyte
Carlo Nyte3mo ago
Thank you for this! And thank you @klequis for asking the question, I'm currently struggling with this and didn't know the correct way to ask it. @peerreynders sorry if this is obvious, but is the advantage of using the cache function is that it actually caches the data so that if the user goes back to the page/ component again there won't be another request made to the server?
peerreynders
peerreynders3mo ago
The intent of the cache is to short circuit duplicate fetches when multiple components on the same route run the same “server function”. By going through the function wrapped in cache only a single fetch is issued and the components can share the processed response. That cached processed response is intended to expire once the route has finished loading so it has an extremely short “maxAge” (the cache timeout seems to be 180 secs). I haven't used it in this way yet but the code seems to suggest that createAsync will reactively receive the most recent value if cache reruns the function/fetch due to a revalidate invalidation.
GitHub
solid-router/src/data/cache.ts at d1a8aab5a3ebfb65726f1aabec80dd42a...
A universal router for Solid inspired by Ember and React Router - solidjs/solid-router
Want results from more Discord servers?
Add your server
More Posts
update JSON.stringify when child object updatesHello, i'm using solidjs in few projects, and I managed to find something I don't really understand Passing State between different routesDo you think this is a good idea to pass data between different pages using solid router. class SeSolid Contexts with Astro for authenticationI am writing a reusable context for authenticating with Auth0, and there are two parts to it. LogginIssue subscribing to store changesI am having trouble understanding why the onClick event of my button in this playground code snippetI have no clue what I am doing wrongHello, I am very new to Solid, I am working with stores right now to represent this data structure: How can I only set the ref for an element once it's been inserted into the DOM?I've tried a few things but it doesn't seem like the element is inserted to the DOM at the point wheIntersection Observer IssuesI'm working on a game and I want some elements to animate in when they become visible, so I'm using what write so as not to constantly write a redirect in every function in case of unauthorizeI don’t have a database on the solidstart server, I only work with third-party APIs. Where to store Solid doesn't re-render when update the same array in createSignalExpected behavior: Re-render inputs every time passwords array is updated even with the same value,For some reason <select> doesn't work correctlyhttps://playground.solidjs.com/anonymous/eedf65f3-e52b-49b0-a8b2-513465a75666 Here it is. When chang