S
SolidJS3mo ago
Hussein

Conditionally redirect based on resource result?

i'm fetching the logged in user using this:
const [user] = createResource(async () => {
const me = await trpc.me.query();
return me;
});
const [user] = createResource(async () => {
const me = await trpc.me.query();
return me;
});
how do i redirect based on whether if user is null to /login page using @solidjs/router?
3 Replies
peerreynders
peerreynders3mo ago
If you are using solid-router have a look at useNavigate and <Navigate />.
Hussein
Hussein3mo ago
how do i make it wait for the resource to finish loading? that's the problem
peerreynders
peerreynders3mo ago
Given you are using solid-router here is an example with cache and createAsync https://docs.solidjs.com/solid-router/reference/data-apis/response-helpers#redirect
// file: src/app.tsx (SolidStart - basic template)
import {
A,
cache,
createAsync,
redirect,
Router,
Route,
} from '@solidjs/router';
import { createSignal, Show, Suspense, useTransition } from 'solid-js';

type User = {
user: string;
};

const incrementCount = (count: number) => count + 1;
const [attempts, set] = createSignal(0);
const increment = () => set(incrementCount);
const reset = () => set(0);

function gamble(cb: (arg: User | null) => never) {
if (Math.random() < 0.3) {
reset();
cb({ user: 'there' });
} else {
increment();
cb(null);
}
}

const getUser = cache(async () => {
console.log('getUser start', Date.now());
const user = await new Promise<User | null>((resolve) => {
setTimeout(gamble, 2000, resolve);
});
if (!user) {
console.log('getUser null');
throw redirect('/');
}

console.log('getUser OK');
return user;
}, 'user');

const loadUser = () => void getUser();
// file: src/app.tsx (SolidStart - basic template)
import {
A,
cache,
createAsync,
redirect,
Router,
Route,
} from '@solidjs/router';
import { createSignal, Show, Suspense, useTransition } from 'solid-js';

type User = {
user: string;
};

const incrementCount = (count: number) => count + 1;
const [attempts, set] = createSignal(0);
const increment = () => set(incrementCount);
const reset = () => set(0);

function gamble(cb: (arg: User | null) => never) {
if (Math.random() < 0.3) {
reset();
cb({ user: 'there' });
} else {
increment();
cb(null);
}
}

const getUser = cache(async () => {
console.log('getUser start', Date.now());
const user = await new Promise<User | null>((resolve) => {
setTimeout(gamble, 2000, resolve);
});
if (!user) {
console.log('getUser null');
throw redirect('/');
}

console.log('getUser OK');
return user;
}, 'user');

const loadUser = () => void getUser();
export default function App() {
return (
<Router
root={(props) => {
const [pending] = useTransition();
return (
<main>
<Suspense>{props.children}</Suspense>
<Show when={pending()}>
<p>Trying…</p>
</Show>
</main>
);
}}
>
<Route
path="/"
component={() => {
return (
<>
<p>
{attempts() > 0
? 'Better luck next time; please try again and c'
: 'C'}
lick below ({attempts()})
</p>
<p>Hovering will start cache preload.</p>
<A href="/about">/about</A>
</>
);
}}
/>
<Route
path="/about"
load={loadUser}
component={() => {
const user = createAsync(() => getUser(), {
deferStream: true,
});

return (
<>
<p>Hello {user()?.user}</p>
<A href="/">/</A>
</>
);
}}
/>
</Router>
);
}
export default function App() {
return (
<Router
root={(props) => {
const [pending] = useTransition();
return (
<main>
<Suspense>{props.children}</Suspense>
<Show when={pending()}>
<p>Trying…</p>
</Show>
</main>
);
}}
>
<Route
path="/"
component={() => {
return (
<>
<p>
{attempts() > 0
? 'Better luck next time; please try again and c'
: 'C'}
lick below ({attempts()})
</p>
<p>Hovering will start cache preload.</p>
<A href="/about">/about</A>
</>
);
}}
/>
<Route
path="/about"
load={loadUser}
component={() => {
const user = createAsync(() => getUser(), {
deferStream: true,
});

return (
<>
<p>Hello {user()?.user}</p>
<A href="/">/</A>
</>
);
}}
/>
</Router>
);
}