Next.js Discord

Discord Forum

Posting form doesn't seem to pass data...

Answered
Forest bachac posted this in #help-forum
Open in Discord
Forest bachacOP
I have the following form (don't judge the password security i'm just using it for testing)
'use client'; import { Container } from 'react-bootstrap'; import React, { useState } from 'react'; import Router from 'next/router' export const SignUpForm: React.FC = () => { const [inputEmail, setEmail] = useState(''); const [inputPassword, setPassword] = useState(''); const submitData = async (e: React.SyntheticEvent) => { console.log('Sending data:'); console.log('Sending data:', inputEmail, inputPassword); e.preventDefault(); try { const body = { inputEmail, inputPassword }; console.log('Sending data:', body); await fetch('/api/users/create', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(body), }); await Router.push('/drafts'); } catch (error) { console.error(error); } }; return ( <Container className="form-signin w-300 m-auto"> <form className="form-signin" onSubmit={submitData}> <h1 className="h3 mb-3 font-weight-normal">Please sign up</h1> <h2 className="h3 mb-3 font-weight-normal">BUT THERE IS NO SECURITY DONT USE A REAL PASSWORD</h2> <label htmlFor="inputEmail" className="sr-only">Email address</label> <input type="email" id="inputEmail" name="inputEmail" onChange={(e) => setEmail(e.target.value)} className="form-control" placeholder="Email address" value={inputEmail} required autoFocus /> <label htmlFor="inputPassword" className="sr-only">Password</label> <input type="password" id="inputPassword" name="inputPassword" onChange={(e) => setPassword(e.target.value)} className="form-control" placeholder="Password" value={inputPassword} required /> <button disabled={!inputEmail || !inputPassword} className="btn btn-lg btn-primary btn-block" type="submit">Sign up</button> <p className="mt-5 mb-3 text-muted">&copy; 2023</p> </form> </Container> ); };

Which submits to

import { getSession } from 'next-auth/react'; import { PrismaClient } from '@prisma/client'; import { NextApiRequest, NextApiResponse } from 'next'; const prisma = new PrismaClient(); export default async function handle(req: NextApiRequest, res: NextApiResponse) { const session = await getSession({ req }); const { inputEmail, inputPassword } = req.body; const result = await prisma.user.create({ data: { email: inputEmail, password: inputPassword, }, }); res.json(result); }

and I get the error
- error src\app\api\users\create\page.tsx (9:10) @ inputEmail
- error TypeError: Cannot destructure property 'inputEmail' of 'req.body' as it is undefined.
at handler (./src/app/api/users/create/page.tsx:16:13)
7 | export default async function handler(req: NextApiRequest, res: NextApiResponse) {
8 | const session = await getSession({ req });
9 | const { inputEmail, inputPassword } = req.body;
| ^
10 |
11 |
12 | const result = await prisma.user.create({

Not sure where to look next(.js)
Answered by joulev
app/api/users/create/route.ts
View full answer

23 Replies

@Forest bachac I have the following form (don't judge the password security i'm just using it for testing) ` 'use client'; import { Container } from 'react-bootstrap'; import React, { useState } from 'react'; import Router from 'next/router' export const SignUpForm: React.FC = () => { const [inputEmail, setEmail] = useState(''); const [inputPassword, setPassword] = useState(''); const submitData = async (e: React.SyntheticEvent) => { console.log('Sending data:'); console.log('Sending data:', inputEmail, inputPassword); e.preventDefault(); try { const body = { inputEmail, inputPassword }; console.log('Sending data:', body); await fetch('/api/users/create', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(body), }); await Router.push('/drafts'); } catch (error) { console.error(error); } }; return ( <Container className="form-signin w-300 m-auto"> <form className="form-signin" onSubmit={submitData}> <h1 className="h3 mb-3 font-weight-normal">Please sign up</h1> <h2 className="h3 mb-3 font-weight-normal">BUT THERE IS NO SECURITY DONT USE A REAL PASSWORD</h2> <label htmlFor="inputEmail" className="sr-only">Email address</label> <input type="email" id="inputEmail" name="inputEmail" onChange={(e) => setEmail(e.target.value)} className="form-control" placeholder="Email address" value={inputEmail} required autoFocus /> <label htmlFor="inputPassword" className="sr-only">Password</label> <input type="password" id="inputPassword" name="inputPassword" onChange={(e) => setPassword(e.target.value)} className="form-control" placeholder="Password" value={inputPassword} required /> <button disabled={!inputEmail || !inputPassword} className="btn btn-lg btn-primary btn-block" type="submit">Sign up</button> <p className="mt-5 mb-3 text-muted">&copy; 2023</p> </form> </Container> ); };` Which submits to `import { getSession } from 'next-auth/react'; import { PrismaClient } from '@prisma/client'; import { NextApiRequest, NextApiResponse } from 'next'; const prisma = new PrismaClient(); export default async function handle(req: NextApiRequest, res: NextApiResponse) { const session = await getSession({ req }); const { inputEmail, inputPassword } = req.body; const result = await prisma.user.create({ data: { email: inputEmail, password: inputPassword, }, }); res.json(result); }` and I get the error - error src\app\api\users\create\page.tsx (9:10) @ inputEmail - error TypeError: Cannot destructure property 'inputEmail' of 'req.body' as it is undefined. at handler (./src/app/api/users/create/page.tsx:16:13) 7 | export default async function handler(req: NextApiRequest, res: NextApiResponse) { 8 | const session = await getSession({ req }); > 9 | const { inputEmail, inputPassword } = req.body; | ^ 10 | 11 | 12 | const result = await prisma.user.create({ Not sure where to look next(.js)
the route handler format is wrong. route handlers don't follow the (req: NextApiRequest, res: NextApiResponse) syntax anymore. it uses export const GET(req: Request) syntax. https://nextjs.org/docs/app/building-your-application/routing/router-handlers#request-body
European sprat
Router in the client component is also being used incorrectly. https://nextjs.org/docs/app/api-reference/functions/use-router
@European sprat Router in the client component is also being used incorrectly. https://nextjs.org/docs/app/api-reference/functions/use-router
Forest bachacOP
Thanks! I hadn't even gotten around to that one yet - I was looking at one of the vercel guides but it was pages vs app directory and a lot of this was based around code i yoinked from there
though that did seem to get it working the way I expected it to for that piece
@joulev the route handler format is wrong. route handlers don't follow the `(req: NextApiRequest, res: NextApiResponse)` syntax anymore. it uses `export const GET(req: Request)` syntax. <https://nextjs.org/docs/app/building-your-application/routing/router-handlers#request-body>
Forest bachacOP
Using the link you send me I'm getting the error:

TypeError: req.formData is not a function

export default async function POST(req: Request) {
const formData = await req.formData();
const inputEmail = formData.get('inputEmail') as string;
const inputPassword = formData.get('inputPassword') as string;
...
Forest bachacOP
Ah I was looking at:
but it gives me
TypeError: request.json is not a function

on await request.json
am i missing a component or something simple
European sprat
You'd need to be sending the content as form data but in your client component you're sending it as application/json
Try what joulev suggested and you should be able to read the JSON
Forest bachacOP
This is that page looks like now

import { NextResponse } from 'next/server'


const prisma = new PrismaClient();

export default async function GET(request: Request) {

const res = await request.json();

/* const inputEmail = formData.get('inputEmail') as string;
const inputPassword = formData.get('inputPassword') as string;



const result = await prisma.user.create({
data: {
email: inputEmail,
password: inputPassword,

},
});
console.log(Response);
*/
return NextResponse.json({ res })

}
still fails at TypeError request.json is not a function
Forest bachacOP
(src/app)/api/users/create/page.tsx
@Forest bachac (src/app)/api/users/create/page.tsx
It must be named route.ts
app/api/users/create/route.ts
Answer
Forest bachacOP
all in all all your alls help helped me a lot
currently functioning and i'll sleep better
!resolved
thanks!