Posting form doesn't seem to pass data...
Answered
Forest bachac posted this in #help-forum
Forest bachacOP
I have the following form (don't judge the password security i'm just using it for testing)
Which submits to
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 });
10 |
11 |
12 | const result = await prisma.user.create({
Not sure where to look next(.js)
'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">© 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)
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">© 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-bodyEuropean 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;
...
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
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 })
}
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
What is the path to the file
Oh yeah and it is export async function not export default async 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!