T
TanStack3mo ago
foreign-sapphire

Hi, I think I was using useServerFn the right way, but it won't redirect... Pls advise

export const loginFn = createServerFn({
method: "POST",
})
.validator((data: FormData) => {
const result = LoginFormSchema.parse(Object.fromEntries(data));
return result;
})
.middleware([convexClientMiddleware])
.handler(async ({ data, context }) => {
...
throw redirect({ to: "/dashboard" });
});

function RouteComponent() {
const { redirectTo } = Route.useSearch();
const login = useServerFn(loginFn);

return (
<div>
<form
onSubmit={async (e) => {
e.preventDefault();
e.stopPropagation();
const formData = new FormData(e.currentTarget);
if (redirectTo) formData.append("redirectTo", redirectTo);
try {
await login({ data: formData });
} catch (error) {
console.log("error", error);
}
}}
>
<Input name="email" placeholder="Email" autoFocus />
<Input name="password" placeholder="Password" type="password" />
</form>
</div>
);
}
export const loginFn = createServerFn({
method: "POST",
})
.validator((data: FormData) => {
const result = LoginFormSchema.parse(Object.fromEntries(data));
return result;
})
.middleware([convexClientMiddleware])
.handler(async ({ data, context }) => {
...
throw redirect({ to: "/dashboard" });
});

function RouteComponent() {
const { redirectTo } = Route.useSearch();
const login = useServerFn(loginFn);

return (
<div>
<form
onSubmit={async (e) => {
e.preventDefault();
e.stopPropagation();
const formData = new FormData(e.currentTarget);
if (redirectTo) formData.append("redirectTo", redirectTo);
try {
await login({ data: formData });
} catch (error) {
console.log("error", error);
}
}}
>
<Input name="email" placeholder="Email" autoFocus />
<Input name="password" placeholder="Password" type="password" />
</form>
</div>
);
}
3 Replies
flat-fuchsia
flat-fuchsia3mo ago
I think this is related to this: https://github.com/TanStack/router/issues/4460. If you create a middleware which check what is returned by the handler like that:
const convertRedirectErrorToExceptionMiddleware = createMiddleware({ type: 'function'})
.server(async ({ next }) => {
const result = await next()
if ('error' in result && isRedirect(result.error)) {
throw result.error
}
return result
})
const convertRedirectErrorToExceptionMiddleware = createMiddleware({ type: 'function'})
.server(async ({ next }) => {
const result = await next()
if ('error' in result && isRedirect(result.error)) {
throw result.error
}
return result
})
if you console.log the result you can see that the redirect "error" is not thrown, so you need to do has shown and the redirect should work.
foreign-sapphire
foreign-sapphireOP3mo ago
Thank you for your help. Can't test it though, because the server-function turned into a get request, although its method is set to POST...
flat-fuchsia
flat-fuchsia3mo ago
Ok, I'm not sure this is related but I think the middleware should come before the validator in your loginFn (maybe it does not matter ^^) ?

Did you find this page helpful?