In one of my component, I'm passing "redirect" & trying to redirect users in specific conditions. But at the time of doing it, I'm getting the following error -
TypeError: props.redirect is not a function
at this piece of code
if (loginForm.response.status) {
throw redirect(302, "/dashboard");
}
Component Code
import { $, component$ } from "@builder.io/qwik";
import { routeLoader$, z, RequestEvent } from "@builder.io/qwik-city";
import type { DocumentHead } from "@builder.io/qwik-city";
import { Link } from "@builder.io/qwik-city";
import type { InitialValues, SubmitHandler } from "@modular-forms/qwik";
import { formAction$, useForm, zodForm$ } from "@modular-forms/qwik";
import { account } from "~/appwrite.config";
const loginSchema = z.object({
email: z
.string()
.min(1, "Please enter your email.")
.email("The email address is badly formatted."),
password: z
.string()
.min(1, "Please enter your password.")
.min(8, "You password must have 8 characters or more."),
});
type LoginForm = z.infer<typeof loginSchema>;
export const useFormLoader = routeLoader$<InitialValues<LoginForm>>(() => ({
email: "",
password: "",
}));
type ResponseData = {
userId: string;
};
export const useFormAction = formAction$<LoginForm>(async (values) => {
console.log("On Server...");
const promise = account.createEmailSession(values.email, values.password);
const result = promise.then(
function (response) {
console.log("Promise Success: ", response);
const userId = response.userId;
return {
status: true,
message: "Authentication successfully done",
data: {
userId: userId,
},
};
},
function (error) {
console.log("Exception Caught: ", error);
return {
status: false,
data: {
error: {
message: error.response.message,
code: error.code,
type: error.type,
version: error.response.version,
},
},
message: "Exception caught when creating user account",
};
}
);
return result;
}, zodForm$(loginSchema));
export default component$(({ redirect }: RequestEvent) => {
const [loginForm, { Form, Field }] = useForm<LoginForm>({
loader: useFormLoader(),
action: useFormAction(),
validate: zodForm$(loginSchema),
});
console.log("loginForm Result: ", loginForm.response);
if (loginForm.response.status) {
throw redirect(302, "/dashboard");
}
type signinFormData = {
email: string;
password: string;
};
const handleSubmit: SubmitHandler<LoginForm> = $(
(values: signinFormData, event) => {
console.log("form data: ", values);
}
);
return (
<>
<section class="bg-gray-50 dark:bg-gray-900">
<div class="flex flex-col items-center justify-center px-6 py-8 mx-auto md:h-screen lg:py-0">
<a
href="#"
class="flex items-center mb-6 text-2xl font-semibold text-gray-900 dark:text-white"
>
<img
class="w-8 h-8 mr-2"
src="https://flowbite.s3.amazonaws.com/blocks/marketing-ui/logo.svg"
alt="logo"
/>
Lemonlist
</a>
<div class="w-full bg-white rounded-lg shadow dark:border md:mt-0 sm:max-w-md xl:p-0 dark:bg-gray-800 dark:border-gray-700">
<div class="p-6 space-y-4 md:space-y-6 sm:p-8">
<h1 class="text-xl font-bold leading-tight tracking-tight text-gray-900 md:text-2xl dark:text-white">
Sign in to your account
</h1>
<Form class="space-y-4 md:space-y-6" onSubmit$={handleSubmit}>
<Field name="email">
{(field, props) => (
<div>
<label
for="email"
class="block mb-2 text-sm font-medium text-gray-900 dark:text-white"
>
Your email
</label>
<input
{...props}
type="email"
value={field.value}
class={[
"bg-gray-50 border text-gray-900 sm:text-sm rounded-lg focus:ring-primary-600 focus:border-primary-600 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500",
field.error ? "border-red-300" : "border-gray-300",
]}
placeholder="name@company.com"
/>
{field.error && (
<p class="mt-2 text-sm text-red-600 dark:text-red-500">
{field.error}
</p>
)}
</div>
)}
</Field>
<Field name="password">
{(field, props) => (
<div>
<label
for="password"
class="block mb-2 text-sm font-medium text-gray-900 dark:text-white"
>
Password
</label>
<input
{...props}
type="password"
value={field.value}
placeholder="••••••••"
class={[
"bg-gray-50 border text-gray-900 sm:text-sm rounded-lg focus:ring-primary-600 focus:border-primary-600 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500",
field.error ? "border-red-300" : "border-gray-300",
]}
/>
{field.error && (
<p class="mt-2 text-sm text-red-600 dark:text-red-500">
{field.error}
</p>
)}
</div>
)}
</Field>
<div class="flex items-center justify-between">
<div class="flex items-start">
</div>
<a
href="#"
class="text-sm font-medium text-primary-600 hover:underline dark:text-primary-500"
>
Forgot password?
</a>
</div>
<button
type="submit"
class="w-full text-white bg-primary-600 hover:bg-primary-700 focus:ring-4 focus:outline-none focus:ring-primary-300 font-medium rounded-lg text-sm px-5 py-2.5 text-center dark:bg-primary-600 dark:hover:bg-primary-700 dark:focus:ring-primary-800"
>
Sign in
</button>
<p class="text-sm font-light text-gray-500 dark:text-gray-400">
Don’t have an account yet?
<Link
href="/account/signup"
class="ml-3 font-medium text-primary-600 hover:underline dark:text-primary-500"
>
Sign up
</Link>
</p>
</Form>
{JSON.stringify(loginForm.response)}
{loginForm.response.status === false &&
(loginForm.response.data.error.type ===
"general_rate_limit_exceeded" ||
loginForm.response.data.error.type ===
"user_invalid_credentials") && (
<>
<div
class="p-4 mb-4 text-sm text-red-800 rounded-lg bg-red-50 dark:bg-gray-800 dark:text-red-400"
role="alert"
>
{loginForm.response.data.error.message}
</div>
</>
)}
</div>
</div>
</div>
</section>
</>
);
});
export const head: DocumentHead = {
title: "Dashboard",
meta: [
{
name: "description",
content: "Qwik site description",
},
],
};
Maybe it's a small mistake; I'm doing it somewhere. But I can't able to understand what it is.
--- Update ---
After using "useNavigate$" in following way it's redirecing to other page but with following error.
if (loginForm.response.status) {
nav("/dashboard");
}
You can use redirect
inside routeAction$
, routeLoader$
, etc. etc. here is the official documentation.
component$ doesn't have redirect
, but you can use useNavigate$