There are four inputs in my form; token_name, token_expire_date, token_issue_date, token_value. The first two require user input however the second two do not (token_issue_date, token_value). These fields are are predetermined however i need them all to end up in the same mongodb document. Here is my pages/index.js file.
import {FieldValues, useForm, UseFormRegister} from "react-hook-form";
import {ToastContainer, toast} from 'react-toastify';
import 'react-toastify/dist/ReactToastify.css';
import useSWR from 'swr';
import React, {useState, useEffect} from "react";
import {useRouter} from "next/router";
const Loading = () => <div>Loading...</div>;
const fetcher = (url) => fetch(url).then(r => r.json())
async function saveFormData(data, url) {
return await fetch(url, {
body: JSON.stringify(data),
headers: {"Content-Type": "application/json"},
method: "POST"
})
}
const Index = () => {
const issuedDate = new Date();
const selectedKey = "123abc";
const tokenPlaceholder = selectedKey;
const fields = [
{type: "text", name: "token_name", required: true, label: "token_name"},
{type: "date", name: "token_expire_date", required: true, label: "token_expire_date"},
{type: "text", name: "token_issue_date", required: true, label: "token_issue_date", placeholder: issuedDate},
{type: "text", name: "token_value", required: true, label: "token_value", placeholder: tokenPlaceholder}
]
const renderForm = ({register, errors, isSubmitting}) => {
return <>
{fields.map(field => {
return (
<>
<label htmlFor={field.name}>{field.label}</label>
<input type={field.type} autoComplete={field.autoComplete} placeholder={field.placeholder}
{...register(field.name, {required: field.required})} />
<div className="error">{errors[field.name]?.message}</div>
</>
)
})}
<button disabled={isSubmitting}>
{isSubmitting ? <Loading/> : "Submit"}
</button>
</>;
}
return <FormComponent url="/api/form" renderForm={renderForm} />
}
function FormComponent({url, renderForm}) {
const {data, error} = useSWR(url, fetcher)
const {register, reset, handleSubmit, setError, formState: {isSubmitting, errors, isDirty}} = useForm();
useConfirmRedirectIfDirty(isDirty)
const onSubmit = async (data) => {
const response = await saveFormData(data, url)
if (response.status === 400) {
// Validation error, expect response to be a JSON response {"field": "error message for that field"}
const fieldToErrorMessage = await response.json()
for (const [fieldName, errorMessage] of Object.entries(fieldToErrorMessage)) {
setError(fieldName, {type: 'custom', message: errorMessage})
}
} else if (response.ok) {
// successful
toast.success("Successfully saved")
} else {
// unknown error
toast.error("An unexpected error occurred while saving, please try again")
}
}
useEffect(() => {
if (data === undefined) {
return; // loading
}
reset(data);
}, [reset, data]);
if (error) {
return <div>An unexpected error occurred while loading, please try again</div>
} else if (!data) {
return <div>Loading...</div>
}
return <form onSubmit={handleSubmit(onSubmit)}>
{renderForm({register, errors, isSubmitting})}
<ToastContainer position="bottom-center"/>
</form>;
}
I am able to get the variables to render as placeholders but i am not able to get them to submit to my database as placeholders... It doesn't seem to work without the user typing anything in. any help would be greatly appreciated!