Reputation: 77
This is my first time trying to make a full stack app. I already have experience with Django but now i wanted to try using Express.js So, i made this simple route in express:
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
var logger = require('morgan');
var User = require('../User/User');
app.use(logger("short"));
app.post("/addUser", (req, res) => {
User.create({
name: req.body.name,
email: req.body.email,
password: req.body.password
}, (err, user) => {
if (err) return res.status(500).json({auth: false})
res.status(200).json(
{
email,
name
}
);
});
});
this is the User schema:
const mongoose = require("mongoose")
const Schema = mongoose.Schema;
const UserSchema = new Schema(
{
name: String,
email: String,
password: String,
},
{timestamps: true}
);
mongoose.model("User", UserSchema);
module.exports = mongoose.model("User");
I already tried doing some post requests using insomnia. They all worked But when i make a post request using react it creates an object but its name, email, password fields are empty, like this:
createdAt: "2018-11-22T16:59:51.844Z"
updatedAt: "2018-11-22T16:59:51.844Z"
__v: 0
_id: "5bf6e0878bd6663807e57dec"
this is my react code - it's in a func that's called when the form is submitted - (I already added the express server as a proxy):
axios.post('/api/auth/addUser', {
name: register_name,
email: register_email,
password: register_password
})
.then(res => res.json())
.catch(err => console.log(err))
I get code 200 on express' console but the obj doesn't have any data. Can you help me? - I'm still a beginner to React and Express
Edit: React Component
import React, { Component } from 'react';
import axios from 'axios';
export default class Register extends Component {
constructor(props) {
super(props)
this.state = {
register_name: "",
register_email: "",
register_password: ""
}
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(event) {
this.setState({[event.target.name]: event.target.value})
}
handleSubmit(event) {
event.preventDefault();
const { register_name, register_email, register_password } = this.state
axios.post('/api/auth/addUser', {
name: register_name,
email: register_email,
password: register_password
})
.then(res => res.json())
.catch(err => console.log(err))
console.log(this.state)
this.clearInputs();
}
render() {
return (
<div>
<form method={"POST"} onSubmit={this.handleSubmit} id={"register-form"}>
<label htmlFor={"register_name"}></label>
<input type={"text"} name={"register_name"} id={"register_name"} placeholder={"name"} value={this.state.register_name} onChange={this.handleChange}></input>
<label htmlFor={"register_email"}>Email</label>
<input type={"email"} name={"register_email"} id={"register_email"} placeholder={"email"} value={this.state.register_email} onChange={this.handleChange}></input>
<label htmlFor={"register_password"} >Password</label>
<input type={"password"} name={"register_password"} id={"register_password"} placeholder={"password"} value={this.state.register_password} onChange={this.handleChange}></input>
<button type={"submit"}>Submit</button>
</form>
</div>
)
}
}
Upvotes: 0
Views: 2341
Reputation: 1465
Everything works out of the box with just bare fetch
.
Here is gist, just make sure you attached bodyParser to express instance
const bodyParser = require('body-parser');
...
app.use(bodyParser.json());
axios lib is useful if you want to upload physical files with FormData
Upvotes: 0
Reputation: 7664
There's a series of potential problems here. First, there's no particular need to make a urlencoded form submission here: just use JSON. Your submit could then look something like:
handleSubmit (e) {
e.preventDefault()
const { email, name, password } = this.state
axios.post('/api/auth/adduser', {
email,
name,
password
})
.then(res => /* ... */)
.catch(err => /* ... */)
}
On the server, you're probably after res.json
rather than res.send
.
const { email, name, password } = req.body
// ...
res.status(201).json({
email,
name
})
Also note that you don't need bodyParser
these days (you can just use express.json()
).
Finally, you should use event.target.name
in your handleChange
as the names match the names of your values in component state:
handleChange (e) {
this.setState({ [e.target.name]: event.target.value })
}
Client:
const CLEAR_STATE = {
email: '',
name: '',
password: '',
message: ''
}
export default class App extends Component {
state = CLEAR_STATE
handleChange = e => this.setState({
[ e.target.name ]: e.target.value
})
handleSubmit = e => {
e.preventDefault()
const { email, name, password } = this.state
axios.post('/', { email, name, password })
.then(({ data }) => this.setState({
...CLEAR_STATE,
message: `You sent: ${data.email}, ${data.name}, ${data.password}.`
}))
.catch(({ message }) => this.setState({ message }))
}
render () {
return (
<>
<form onSubmit={this.handleSubmit}>
<input
type='text'
name='email'
value={this.state.email}
onChange={this.handleChange} />
<input
type='text'
name='name'
value={this.state.name}
onChange={this.handleChange} />
<input
type='password'
name='password'
value={this.state.password}
onChange={this.handleChange} />
<input type='submit' value='Register' />
</form>
{this.state.message && <p>{this.state.message}</p>}
</>
)
}
}
Server:
app.use(express.json())
app.post('/', (req, res) => {
const { name, email, password } = req.body
res.status(201).json({ name, email, password })
})
Upvotes: 0
Reputation: 196236
You are using the [event.target.id]
of the changed input
element to update the state.
You state
expects name
,email
,password
but receives register_name
,register_email
,register_password
.
You should change the id
of the input
elements to match those in the state or you should use the name
attribute since that is what matches .
this.setState({[event.target.name]: event.target.value});
Keep in mind that the attribute htmlFor
of the label
elements also needs to match the id
and not the name
of the element it is linked to.
Also, you should have noticed that something was wrong since your code will not update the input
elements while you type.
Upvotes: 1