#How can I show the error on client side when I have full server component?
1 messages · Page 1 of 1 (latest)
In your current setup, you are throwing an error in the server component when the response is not okay. However, this error is not being caught and handled on the client side.
To show the error on the client side, you can use React's state to handle the error message. Here is an example from the Next.js documentation:
import React, { useState, FormEvent } from 'react'
export default function Page() {
const [isLoading, setIsLoading] = useState<boolean>(false)
const [error, setError] = useState<string | null>(null)
async function onSubmit(event: FormEvent<HTMLFormElement>) {
event.preventDefault()
setIsLoading(true)
setError(null) // Clear previous errors when a new request starts
try {
const formData = new FormData(event.currentTarget)
const response = await fetch('/api/submit', {
method: 'POST',
body: formData,
})
if (!response.ok) {
throw new Error('Failed to submit the data. Please try again.')
}
// Handle response if necessary
const data = await response.json()
// ...
} catch (error) {
// Capture the error message to display to the user
setError(error.message)
console.error(error)
} finally {
setIsLoading(false)
}
}
return (
<div>
{error && <div style={{ color: 'red' }}>{error}</div>}
<form onSubmit={onSubmit}>
<input type="text" name="name" />
<button type="submit" disabled={isLoading}>
{isLoading ? 'Loading...' : 'Submit'}
</button>
</form>
</div>
)
}
In this example, an error state is initialized with useState. When the form is submitted, the error state is cleared. If an error occurs during the fetch request, the error message is set in the error state. This error message is then displayed in the form.
You can adapt this example to your needs. For instance, you can replace the fetch URL with your login API endpoint, and the form data with your login form data.
Source: Next.js Documentation (https://nextjs.org/docs/pages/building-your-application/data-fetching/forms-and-mutations#error-handling)
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
@solemn gull I don't want to make the whole component as a client one
Let me check the knowledge base for you. One moment! :books:
If you want to keep the component as a server component but handle errors on the client side, you can use a hybrid approach. You can use a client component to handle the form submission and error handling, while the rest of the component remains a server component.
Here's an example of how you can modify your LoginForm component to handle errors on the client side:
import { useState } from 'react';
import { Button, Form, Input, message } from "antd";
import { toUpperCase } from "../../utils";
import FormItem from "antd/lib/form/FormItem";
import InputPassword from "antd/lib/input/Password";
import { Icons } from "../Icons";
import { redirect } from "next/navigation";
import { cookies } from "next/headers";
import Link from "next/link";
const LoginForm = () => {
const [error, setError] = useState(null);
const login = async (values) => {
"use server";
const response = await fetch(
`${process.env.NEXT_PUBLIC_API_URL}/auth/login`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(values),
}
);
if (!response.ok) {
setError("ელ.ფოსტა ან პაროლი არასწორია!");
return;
}
redirect("/");
};
return (
<Form onFinish={login} size="large">
{error && <div>{error}</div>}
<FormItem
name="email"
rules={[
{ required: true, message: "ელ.ფოსტა აუცილებელია!", type: "email" },
]}
>
<Input placeholder={toUpperCase("ელ.ფოსტა")} />
</FormItem>
<FormItem
name="password"
rules={[{ required: true, message: "პაროლი აუცილებელია!" }]}
>
<InputPassword placeholder={toUpperCase("პაროლი")} autoComplete="on" />
</FormItem>
<Link
href="/reset-password"
className="text-xs text-secondary text-opacity-50 hover:text-opacity-80 hover:text-secondary mb-2 block"
>
{toUpperCase("პაროლის")}{" "}
<span className="text-primary underline">{toUpperCase("აღდგენა")}</span>
</Link>
<Button type="primary" htmlType="submit" icon={<Icons.sendIcon />}>
{toUpperCase("გაგზავნა")}
</Button>
</Form>
);
};
export default LoginForm;
In this example, I've added a `useState` hook to manage the error state. When the response from the fetch request is not okay, I set the error state to the error message. This error message is then displayed in the form.
Please note that this is a simplified example and you might need to adjust it according to your needs.
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------