So far I have a Next.js app with a form component that looks like this:
components/Form.js
import { useState } from 'react'
import { useRouter } from 'next/router'
import { mutate } from 'swr'
const Form = ({ formId, demoForm, forNewDemo = true }) => {
const router = useRouter()
const contentType = 'application/json'
const [errors, setErrors] = useState({})
const [message, setMessage] = useState('')
const [form, setForm] = useState({
projectName: demoForm.projectName,
projectFunction: demoForm.projectFunction,
})
/* The PUT method edits an existing entry in the mongodb database. */
const putData = async (form) => {
const { id } = router.query
try {
const res = await fetch(`/api/demos/${id}`, {
method: 'PUT',
headers: {
Accept: contentType,
'Content-Type': contentType,
},
body: JSON.stringify(form),
})
// Throw error with status code in case Fetch API req failed
if (!res.ok) {
throw new Error(res.status)
}
const { data } = await res.json()
mutate(`/api/demos/${id}`, data, false) // Update the local data without a revalidation
router.push('/')
} catch (error) {
setMessage('Failed to update')
}
}
/* The POST method adds a new entry in the mongodb database. */
const postData = async (form) => {
try {
const res = await fetch('/api/demos', {
method: 'POST',
headers: {
Accept: contentType,
'Content-Type': contentType,
},
body: JSON.stringify(form),
})
// Throw error with status code in case Fetch API req failed
if (!res.ok) {
throw new Error(res.status)
}
router.push('/')
} catch (error) {
setMessage('')
}
}
const handleChange = (e) => {
const target = e.target
const value =
target.name === 'poddy_trained' ? target.checked : target.value
const name = target.name
setForm({
...form,
[name]: value,
})
}
/* Makes sure demo info is filled for demo name, owner name, species, and image url*/
const formValidate = () => {
let err = {}
if (!form.projectFunction) err.projectFunction = 'Function is required'
return err
}
const handleSubmit = (e) => {
e.preventDefault()
const errs = formValidate()
if (Object.keys(errs).length === 0) {
forNewDemo ? postData(form) : putData(form)
} else {
setErrors({ errs })
}
}
return (
<>
<form id={formId} onSubmit={handleSubmit}>
<textarea
name="projectFunction"
value={form.projectFunction}
onChange={handleChange}
/>
<input
name="projectName"
value={form.projectName}
onChange={handleChange}
/>
<button type="submit" className="btn">
Submit
</button>
</form>
<div>
{Object.keys(errors).map((err, index) => (
<li key={index}>{err}</li>
))}
</div>
</>
)
}
export default Form
the form is located at the /new page
pages/new.js
import Form from '../components/Form'
const New = () => {
const demoForm = {
projectFunction: [],
projectName: []
}
return <Form formId="add-demo-form" demoForm={demoForm} />
}
export default New
and here is my api at pages/api/demos/index.js
import dbConnect from '../../../lib/dbConnect'
import Demo from '../../../models/Demo'
import fs from 'fs'
export default async function handler(req, res) {
const {
method,
body,
} = req
await dbConnect()
switch (method) {
case 'POST':
try {
const timestamp = (JSON.parse(JSON.stringify(new Date())));
const newJsonDirectory = "projects/" timestamp;
const newJsonFile = newJsonDirectory ".json";
fs.writeFileSync(newJsonFile, JSON.stringify([ "date: " Date.now().toString(), "name: " body.projectName, "display: projects", "route: " newJsonFile]));
const demo = await Demo.create(
req.body
)
res.status(201).json({ success: true, data: demo })
} catch (error) {
res.status(400).json({ success: false })
}
break
default:
res.status(400).json({ success: false })
break
}
}
lets say I submit my values into the form textarea: projectFunction
function() {
echo "hello"
}
input: projectName
hello-world
the projects folder would then contain a file that looks like this
2022-09-10T233306.465Z.json
and its contents
["date: 1662852786465","name: hello-world","display: projects","route: projects/2022-09-10T23:33:06.465Z.json"]
I am relatively new to node.js and have been having difficulty responding with a nested JSON object. I am not sure I am even doing this right... :/ My goal is to return something like this!
{
"order": [
{
"name": "hello-world",
"pages": [
{
"display": "projects",
"subpages": [
{ "route": "", "display": "projects/2022-09-10T22:53:49.346Z.json" }
]
}
]
}
]
}
If anyone could help me out it would be greatly appreciated!
CodePudding user response:
Try this
JSON.stringify({ "order": [ { "name": "hello-world", "pages": [{ "display": "projects", "subpages": [{ "route": "", "display": "projects/2022-09-10T22:53:49.346Z.json" }] }]} ] })
instead of
JSON.stringify([ "date: " Date.now().toString(), "name: " body.projectName, "display: projects", "route: " newJsonFile])
also, remove hardcoded strings with variable/function calls