Send Data from React JS Form to Back Express - javascript

I created a react, express app and then created a simple form in React app that accepts name and age and on submit the form data is supposed to go to backend express app and console log there but I can not access the form input data in my backend express.On submit I get this {"message":"Hello World"} logged in my console of react page.
//express app.js
const express = require('express');
const cors = require('cors');
const app = express()
app.use(cors())
app.use(express.urlencoded())
app.use(express.json())
app.use("/",(req,res)=>{
res.json({ message: "Hello World" });
})
app.post('/', (req, res) => {
const { fullname, age } = req.body;
console.log(fullname, age);
res.send('Form submitted successfully');
});
app.listen(5000,()=>{console.log("http://localhost:5000");})
My login react app:
import React from "react";
export default function App(){
function submitHandler(e){
e.preventDefault();
const fullname = e.target.elements.fullname.value;
const age = e.target.elements.age.value;
fetch('http://localhost:5000/', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ fullname, age })
})
.then(response => response.text())
.then(data => {
console.log(data);
});
}
return (
<div className="App">
<form onSubmit={submitHandler}>
<input type="text" name="fullname" id="" placeholder="Name:" />
<input type="number" name="age" id="" placeholder="age" />
<input type="submit" value="Submit" />
</form>
</div>
);
}
Help me get the form input data in express app so that I can later store it in mongodb

You must replace app.use with app.get
app.get("/",(req,res)=>{
res.json({ message: "Hello World" });
})
see documentation of app.use

Related

req.body is an empty object express/nodejs [duplicate]

This question already has an answer here:
ExpressJS request body is empty if i don't use multer
(1 answer)
Closed 7 months ago.
I have a form with two numeric input fields that I'd like to send to the backend, but req.body is always empty. Here is my form:
<form
class="mt-3"
id="myForm"
enctype="multipart/form-data"
action="/submit-thing1and2"
>
<div class="mb-2">
<label for="thing1" class="form-label"
>Thing 1</label
>
<input
type="number"
class="form-control"
id="thing1"
name="thing1"
required
/>
</div>
<div class="mb-2">
<label for="thing2" class="form-label"
>Thing 2</label
>
<input
type="number"
class="form-control"
id="thing2"
name="thing2"
required
/>
</div>
<div class="form-group-row mb-3">
<button id="submitThings" type="submit" class="btn btn-primary">
Submit Things
</button>
</div>
</form>
I have tried using enctype="application/json", "text/html", and "application/x-www-form-urlencoded", and all of them still return an empty object in req.body.
Here is my post request:
form = document.getElementById("myForm");
form.addEventListener("submit", async (event, arg) => {
event.preventDefault();
console.log(event.target.action);
console.log(event.target);
let data = new FormData(event.target);
console.log(data.toString());
fetch(event.target.action, {
method: "post",
body: new FormData(event.target),
})
.then((res) => {
console.log(res.status);
return res.text();
})
.then((data) => {
console.log(data);
});
});
And here is my server-side handling of the post request - the console.log works, just shows an empty object:
const express = require("express");
const path = require("path");
const PORT = process.env.PORT || 5000;
const app = express();
app.use(express.static(path.join(__dirname)));
app.use(express.json());
app.use(
express.urlencoded({
extended: true,
})
);
app.post("/submit-thing1and2", async (req, res) => {
console.log("req.body", req.body);
res.send(req.body);
});
app.get("/", (req, res) => {
res.sendFile("./html/index.html", { root: __dirname });
});
app.listen(PORT, () => console.log(`Listening on ${PORT}`));
Use multer to parse multipart/form-data requests:
app.post("/submit-thing1and2",
multer().fields([{name: "thing1"}, {name: "thing2"}]),
async function(req, res) {
...
});

How to store the textbox data (from react.js) into mongoDB using node.js

How to store the textbox data (from react.js) into mongoDB using node.js?
I want to store the text as soon as person click the button (should store in mongoDB cloud). All the connection was successful.
This is my code
App.js (in server)
const mongoose = require("mongoose");
const express = require("express");
const app = express();
// Connection URL
const url = "mongodb+srv://dbname:pass#cluster0.gkqcs.mongodb.net/myApp?etryWrites=true&w=majority";
// Use connect method to connect to the Server
mongoose.connect(url,).then(() =>
{
console.log("connection successful");
}).catch((err) => console.log("not connected"));
App.js (Frontend using react.js)
function App() {
return (
<div className="App">
<div className="container">
<div className="eleContainer">
<input type="text" className="txtAdd" placeholder="Type New Word"/>
<button className="addNew">Add to Dictionary</button>
<br />
<br />
<input type="text" className="searchWords" placeholder="Search here"/>
<br />
<br />
<ol className="vocabularyList">
<li>words</li>
</ol>
</div>
</div>
</div>
);
}
Front end
function App() {
const [textAddValue, updateInput] = useState("");
const addNewText = () =>{
//send form data to server.
//use library like axios.
if(!textAddValue){ alert('input empty'); return;}
fetch('http://localhost:5000/sendText', {
headers: {
'Cache-Control': 'no-cache',
"Content-Type": "application/json",
'Accept': "application/json",
},
method: "POST",
body: JSON.stringify({text: textAddValue})
})
.then(res=>res.json())
.then(result=>console.log(result))
.catch(err=>{console.log(err)})
}
return (
<div className="App">
<div className="container">
<div className="eleContainer">
<input type="text" className="txtAdd" placeholder="Type New Word" value={textAddValue} onChange={(e)=>updateInput(e.target.value)}/>
<button className="addNew" onClick={addNewText}>Add to Dictionary</button>
<br />
<br />
<input type="text" className="searchWords" placeholder="Search here"/>
<br />
<br />
<ol className="vocabularyList">
<li>words</li>
</ol>
</div>
</div>
</div>
);
}
Backend
const mongoose = require("mongoose");
const express = require("express");
const app = express();
//configure app for incoming post data
const expressJson = express.json();
const bodyParser = express.urlencoded({extended: true});
app.use([expressJson, bodyParser])
// Connection URL
const url = "mongodb+srv://dbname:pass#cluster0.gkqcs.mongodb.net/myApp?etryWrites=true&w=majority";
// Use connect method to connect to the Server
mongoose.connect(url,).then(() =>
{
console.log("connection successful");
}).catch((err) => console.log("not connected"));
app.post('/sendText', (req, res)=>{
const text = req.body.text;
//you need to create mongoose schema to save. saveSchema here I'm asuming.
saveSchema.save({text: text})
.then(res=>{res.json("Saved")})
.catch(err=>{console.log(err); res.json("Error! cannot save")}
});
app.listen(5000, ()=>{console.log("Server running at port 5000")});

Email api using react node nodemailer express is not working

I am trying to create an contact page using ReactJs NodeJs express and nodemail. I am not getting any error. But it's not working. The post request is not working so i guess there's something wrong with the axios function but it could be anywhere else too so.Is the error in the backend part or the frontend part How do i fix it?
Post Log saying
Proxy error: Could not proxy request /api/forma from localhost:3000 to localhost:3001 (ECONNRESET)
Client side
import React,{useState} from 'react'
import axios from 'axios';
const Form = () => {
const [name,setName] = useState("");
const [email,setEmail] = useState("");
const [message,setMessage] = useState("");
const [sent,setSent] = useState(false);
const formSubmit=(e)=> {
e.preventDefault();
let data = {
name:name,
email:email,
message:message
}
axios.post('/api/forma',data)
.then(res => {
setSent(true);
},resetForm())
.catch(() => {
console.log("message not sent");
})
}
const resetForm = () => {
setName("");
setEmail("");
setMessage("");
setTimeout(()=> {
setSent(false);
},3000)
}
return (
<div className="container">
<form onSubmit={formSubmit}>
<div className="single">
<label>Name</label>
<input type="text" name="name" className="name" placeholder="Enter your name"
value={name}
onChange={e => setName(e.target.value)}
/>
</div>
<div className="single">
<label>Email</label>
<input type="text" name="email" className="email" placeholder="Enter your email"
value={email}
onChange={e => setEmail(e.target.value)}/>
</div>
<div className="textarea">
<label>Message</label>
<textarea name="message" id="" cols ="30" rows="5" placeholder="Enter your message here"
value={message}
onChange={e => setMessage(e.target.value)}></textarea>
</div>
<div className={sent?'msg msgAppear':'msg'}>
Message has been sent
</div>
<div>
<button type="submit">submit</button>
</div>
</form>
</div>
)
}
export default Form
Server side
const express = require('express');
const bodyParser = require('body-parser');
const nodemailer = require('nodemailer')
const cors = require('cors')
const app = express();
app.use(bodyParser.json);
app.use(bodyParser.urlencoded({extended:true}));
app.use(cors());
app.get('/',()=>{
resizeBy.send("Welcome")
});
app.post('/api/forma',(req,res) => {
let data = req.body
let smtptransport = nodemailer.createTransport({
service:'Gmail',
port:465,
auth:{
user:'yourEmail#gmail.com',
pass: "secreate"
}
});
let mailOptions = {
from:data.email,
to:'yourEmail#gmail.com',
subject:`Message from ${data.name}`,
html:`
<h3>Informations<h3>
<ul>
<li>Name: ${data.name}</li>
<li>Name: ${data.email}</li>
</ul>
<h3>Message<h3>
<p>${data.message}</p>
`
}
smtptransport.sendMail(mailOptions,(error,response) => {
if(error){
res.send(error)
}
else{
res.send('Success')
}
})
smtptransport.close();
})
const PORT = process.env.PORT || 3001;
app.listen(PORT,() => {
console.log(`Server starting at port ${PORT}`);
})
One way to solve this using gmail is creating a transporter.
Here is the working code:
mail.service.js
const nodemailer = require('nodemailer');
const transporter = nodemailer.createTransport({
service: 'Gmail',
auth: {
user: '<myuser>#gmail.com',
pass: '<mypassword>'
},
logger: false, // log to console
debug: false // include SMTP traffic in the logs
});
exports.sendEmail = function(req, res) {
const mailOptions = {
from: '<myuser>#gmail.com',
subject: 'My custom title ',
text: 'Mensagem de: ' + req.body.nome + ', email: [' + req.body.email + '] ' + req.body.mensagem,
to: req.body.email
}
transporter.sendMail(mailOptions).then((trans) => {
res.status(200);
res.json(trans);
res.end();
}).catch((error) => {
res.status(500);
res.json(error);
res.end();
});
}
Here is my router for sendemail action:
const router = require('express').Router();
const emailService = require('../services/mail.service.js');
router.post('/sendmail', emailService.sendEmail);
module.exports = router;
If you are in some situation of 403 errors you might need to do this configurations steps provided by nodemailer (this configuration is in gmail account) .

express body-parser returns empty body in req object

I am a beginner to react and node and this will be a very basic problem.
I am creating a basic react fronted with a node backend. I setup mysql database connection and all set. I want to insert user details using /createUser api call to store data to database.
I run the server/app.js, react serve and index.js which contained my listener for /createUser.
When I input username,password using my form, empty req.body object will be returned in express.post method while I am expecting the username and password I entered.
In other case, when I start the listener, react front is not loading by giving the error below.
GET http://localhost:3000/%PUBLIC_URL%/manifest.json 404 (Not Found)
manifest.json:1 Manifest: Line: 1, column: 1, Unexpected token.
It seems like node component cannot access my manifest file. Am I correct?
index.js
const express = require('express');
const bodyParser = require('body-parser');
const store = require('./store');
const app = express();
app.use(express.static('public'));
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json({ type: 'application/*+json' }));
app.use(bodyParser.json());
app.post('/createUser', (req, res) => {
console.log(req.body);
store
.createUser({
username: req.body.username,
password: req.body.password
})
.then(() => res.sendStatus(200))
})
app.listen(3001, () => {
console.log('Server running on http://localhost:3001')
})
login.js
import React, { Component } from 'react';
import classes from './Login.css';
function post (path, data) {
console.log(data);
return window.fetch(path, {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify(data)
})
}
function handleLoginClick(e) {
e.preventDefault();
console.log('The link was clicked.');
const Login = document.querySelector('.Login');
const username = Login.querySelector('.username').value;
const password = Login.querySelector('.password').value;
post('/login', { username, password })
.then(({ status }) => {
if (status === 200) alert('login success')
else alert('login failed')
})
}
function handleSignupClick(e) {
e.preventDefault();
console.log('The link was clicked sign up.');
const CreateUser = document.querySelector('.CreateUser')
const username = CreateUser.querySelector('.username').value;
const password = CreateUser.querySelector('.password').value;
post('/createUser', { username, password })
}
class Login extends Component {
componentDidMount() {
}
componentWillUnmount() {
}
render() {
return (
<div>
<form className="Login">
<h1>Login</h1>
<input type="text" className="username" placeholder="username"/>
<input type="password" className="password" placeholder="password"/>
<input type="submit" value="Login" onClick={handleLoginClick}/>
</form>
<form className="CreateUser">
<h1>Create account</h1>
<input type="text" className="username" placeholder="username"/>
<input type="password" className="password" placeholder="password"/>
<input type="submit" value="Create" onClick={handleSignupClick}/>
</form>
</div>
);
}
}
export default Login;
What's wrong with my code? Can someone please explain me.
my code : https://github.com/indunie/tms2
Try to replace bodyParser configuration to following lines of code:
app.use(bodyParser.json({ limit: '100mb' }));
app.use(bodyParser.urlencoded({ limit: '100mb', extended: false }));
This might help you
solved [https://github.com/expressjs/express/issues/3881][1]
There are two solutions here:
Change the URL to http://localhost:3001/manifest.json to match how you have express.static setup.
Change express.static to app.use('/public', express.static('public')); such that http://localhost:3001/public/manifest.json will refer to the given file.

How to extract body from request with express in NodeJs?

I'm using Node.Js and express framework for my application.
I build HTML forms and upon submitting I'm not able to receive my form data on API request.
My HTML:
<form method="post" action="/create">
<input type="text" name="user.name" />
<input type="text" name="user.email" />
<input type="text" name="user.address.city" />
<input type="text" name="user.address.land" />
<input type="submit" value="Submit">
</form>
JSON object should been obtained at my API:
{
"user": {
"name": "toto",
"email": "toto#mail.com",
"address": {
"city": "yyyyy",
"land": "zzzz"
}
}
}
How to do this with Node.js, Express 4 and is there another library for this?
You can prepare your own middleware that parses the incoming form data using body-parser's urlencoded() and turns it into a structured JSON:
const express = require('express');
const bodyParser = require('body-parser');
const app = express();
function setDeepValue(path, obj, value) {
const tokens = path.split('.');
const last = tokens.pop();
for (const token of tokens) {
if (!obj.hasOwnProperty(token)) {
obj[token] = {};
}
obj = obj[token];
}
obj[last] = value;
}
app.use(bodyParser.urlencoded(), function(req, res, next) {
let obj = {};
for (const key in req.body) {
setDeepValue(key, obj, req.body[key]);
}
req.body = obj;
next();
});
app.post('/create', function(req, res) {
console.log(req.body)
})
In your HTML code you are posting to a create route.
So in express you need to create that route
const express = require('express')
const bodyParser = require('body-parser')
const app = express()
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({ extended: true }))
app.post('/create', function(req, res) {
console.log('----- MY BODY -----')
console.log(req.body)
// do something more clever
res.send('We posted to this route')
})
First we require express, then we require body-parser and finally initialize our express app.
We then use the json middlewere of body-parser to parse the body so that we can easily access it in our handler.
We then define a route to '/create' that accepts posts request (remember that your form is posting to this location).
All that our handler does is to console.log the body of the request, and then shows the message We posted to this route
Follow this guide repository specially created to guide freshers nodejs-frontend-sample-for-freshers
EDIT:
You can use Ajax call to submit form this will also help in Single Page Application
Client-side JS:
function submit() {
// JavaScript uses `id` to fetch value
let email = $("#email").val(),
name = $("#name").val(),
city = $("#city").val(),
land = $("#land").val();
// Can validate each field here and show error like:
if ( validateEmail(email) ) {
$("#emailError").addClass("hide");
} else {
$("#emailError").removeClass("hide");
return;
}
// form request data, doing this will get you data in correct form at NodeJs API
let data = {
user: {
email,
name,
address: {
city,
land
}
}
};
$.ajax({
"url": "/create",
"method": "POST",
"data": data
})
.then( result => {
// On success empty all the input fields.
$("#email").val('');
$("#name").val('');
$("#city").val('');
$("#land").val('');
// Message to notify success submition
alert("Successfully added user.");
return;
})
.catch( err => {
// Notify in case some error occured
alert("An error occured.");
return;
});
}
// Validate Email based upon pattern
function validateEmail (email) {
if ( email && email.match(/^([A-z0-9_.]{2,})([#]{1})([A-z]{1,})([.]{1})([A-z.]{1,})*$/) ) {
return true;
}
return false;
}
HTML:
<form>
<input type="text" id="name" />
<input type="text" id="email" />
<span id="emailError" class="hide error">Valid Email Required</span>
<input type="text" id="city" />
<input type="text" id="land" />
<p onclick="submit()">Submit</p>
</form>
Would recommend you to use cors.js too like:
const cors = require('cors');
// Cross-Origin Resource Sharing
app.use(cors());
You can get object in two ways:
1: Using no extra module something like this
app.post('/create', function (request, response, next) {
let body = [];
request.on('error', (err) => {
console.error(err);
}).on('data', (chunk) => {
body.push(chunk);
}).on('end', () => {
body = Buffer.concat(body).toString();
console.log(body); // Your object
request.body = body; // Store object in request again
next();
});
}, (req, res) => {
console.log(req.body); // This will have your object
});
Using body-parser with express:
```
// configure the app to use bodyParser() to extract body from request.
// parse urlencoded types to JSON
app.use(bodyParser.urlencoded({
extended: true
}));
// parse various different custom JSON types as JSON
app.use(bodyParser.json({ type: 'application/*+json' }));
// parse some custom thing into a Buffer
app.use(bodyParser.raw({ type: 'application/vnd.custom-type' }));
// parse an HTML body into a string
app.use(bodyParser.text({ type: 'text/html' }));
app.post('/create', function (request, response, next) {
console.log(request.body); // `body-parser did what I did earlier`
});
```

Categories

Resources