Using React js to submit some text boxes to SQL database - node.js

I am trying to submit a couple text boxes to my SQL database using React js through a post request, then on the server side I am listening for the post and querying the data to my database. Right now both values are returning "undefined" regardless of what the user inputs into the form, so I think I've screwed up the React side code. This is the code I am using
Server.js:
var express = require('express');
var app = express();
var sql = require("mssql");
const bodyParser = require('body-parser');
app.use(bodyParser.json());
var config = {
user: 'user',
password: 'pass',
server: 'localhost',
database: 'Master'
};
app.post('/', function(req, res) {
res.set('Access-Control-Allow-Origin', '*');
const { FirstName, LastName } = req.body;
let connection = new sql.ConnectionPool(config, function(err) {
let request = new sql.Request(connection);
request.query("insert into persons (FirstName, LastName) values ('" + FirstName + "', '" + LastName + "')");
});
res.send({ message: 'Success'})
});
app.listen(5000, () => {console.log('Server is running..')});
And here is my react code...
postData.js:
import React, { Component } from 'react';
class postData extends Component {
constructor() {
super();
this.state = { user: {} };
this.onSubmit = this.handleSubmit.bind(this);
}
handleSubmit(e) {
e.preventDefault();
var self = this;
// On submit of the form, send a POST request with the data to the server.
fetch('http://localhost:5000', {
method: 'POST',
body: {
FirstName: self.refs.FirstName,
LastName: self.refs.LastName
}
})
.then(function(response) {
return response.json()
}).then(function(body) {
console.log(body);
});
}
render() {
return (
<form onSubmit={this.onSubmit}>
<input type="text" placeholder="First Name" ref="FirstName"/>
<input type="text" placeholder="Last Name" ref="LastName"/>
<input type="submit" />
</form>
);
}
}
export default postData;
Again, I'm pretty sure I've screwed up the code on the React side, but I'm pretty new to all this so I'm not sure where to start troubleshooting. When I console.log the req.body on the server side it just returns {}, so it seems like there isn't any data being sent from the react script.
Thanks!

Thanks for all the help guys. I incorporated a lot of the recommendations you guys gave, but the final straw was the following in my server.js code
app.use(express.json({
type: ['application/json', 'text/plain']
}));
Once I included this change I was able to eliminate the undefined error I was getting

Add these lines on fetch request:
fetch('http://localhost:5000',
{ method: 'POST',
headers: new Headers({
"Content-Type":"application/json"
}),
body: JSON.stringify({
FirstName: self.refs.FirstName,
LastName: self.refs.LastName })
})
Then in your server
app.post('/', function(req, res) {
res.set('Access-Control-Allow-Origin', '*');
const body = JSON.parse(req.body);
let connection = new sql.ConnectionPool(config, function(err) {
let request = new sql.Request(connection);
request.query("insert into persons (FirstName, LastName) values ('" + body.FirstName + "', '" + body.LastName + "')");
});
res.send({ message: 'Success'})
});
Hope this helps.

To make your code work just replace this part:
body: {
FirstName: self.refs.FirstName,
LastName: self.refs.LastName
}
by this:
body: {
FirstName: self.refs.FirstName.value,
LastName: self.refs.LastName.value
}
but I would suggest you to do just like #Yousaf did, and use React.createRef(); to create refs to elements in React

Related

React Button that Submits Express Backend Post Request to add to Firebase Cloud Firestore

I have an express.js backend that handles routes and some mock data that is accessed via certain routes. Additionally, there is a get request and post request for receiving and adding documents respectively to the Firestore collection, "books".
const express = require('express');
const app = express();
const port = 8000
const cors = require("cors")
const db = require('./firebase');
app.use(express.json());
app.use(cors());
const stores = [
{
author: 'John Snape',
title: 'Random Book'
},
{
author: 'Herman Melville',
title: 'Moby Dick'
},
{
author: 'William Shakespeare',
title: 'Hamlet'
},
{
author: 'Homer',
title: 'The Iliad'
},
{
author: 'Albert Camus',
title: 'The Stranger'
},
{
author: 'George Eliot',
title: 'Middlemarch'
},
{
author: 'Charles Dickens',
title: 'Great Expectations'
},
{
author: 'William Faulkner',
title: 'The Sound and the Fury'
},
]
//Getting documents in collection "books"
app.get("/books/get", async (req, res) => {
const snapshot = await db.collection("books").get();
const books = [];
snapshot.forEach((doc) => {
books.push({ ...doc.data(), id: doc.id });
});
res.send(books);
});
//Post request for adding document to Firestore Collection "books"
app.post("/books/add", async (req, res) => {
const { title, author } = req.body;
const resp = await db.collection("books").add({
title: req.body.title,
author: req.body.author,
});
res.sendStatus(200);
});
//accessing the mock data
app.get("/api/stores", function(req, res){
res.json(stores)
})
//querying for a specific title
app.get("/api/stores/:title", function(req, res){
const query = req.params.title;
var result=null;
for(var index = 0; index<stores.length; index++){
var item = stores[index];
if(item.title === query){
result = stores[index];
}
}
res.send(result);
});
app.listen(port, () => {
console.log(`Example app listening at http://localhost:${port}`)
});
I know that the above requests for the express server are working properly as I have tested each request out and used Postman for the Post request.
Now, for the frontend via react, I have displayed the titles and authors from stores (mock data) in a list and given each element in the list a button, which will be used for saving it to the Firestore collection via the POST request from express ('/books/add'). Here is the React code for that component:
import React, { Component } from 'react';
export default class Search extends Component{
constructor(props){
super(props)
this.state = {
results: [],
author: '',
title: '',
};
}
//the below fetch is a get request that gets the elements from the stores variable in the express server.
componentDidMount(){
fetch('/api/stores')
.then(res => res.json())
.then(results => this.setState({results}, ()=> console.log('Books fetched...', results)));
}
render() {
return (
<div>
<h2>result</h2>
<ul>
{this.state.results.map(resu =>
<li key={resu.id}>{resu.title} - {resu.author}
<button/>
</li>
)}
</ul>
</div>
);
}
}
Does anybody know a way to have the POST request take place with the Button's onClick so that the corresponding title and author at that element in the list is passed as a document to the Firestore collection?
This should work. You need to call a function to do post request on the click of the button.
import React, { Component } from 'react';
export default class Search extends Component{
constructor(props){
super(props)
this.state = {
results: [],
author: '',
title: '',
};
}
//the below fetch is a get request that gets the elements from the stores variable in the express server.
componentDidMount(){
fetch('/api/stores')
.then(res => res.json())
.then(results => this.setState({results}, ()=> console.log('Books fetched...', results)));
}
handleSave(data) {
fetch('/books/add'
{
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
method: "POST",
body: JSON.stringify(data)
})
.then(function(res){ console.log(res) })
}
render() {
return (
<div>
<h2>result</h2>
<ul>
{this.state.results.map(resu =>
<li key={resu.id}>{resu.title} - {resu.author}
<button onClick={() => this.handleSave(resu)}/>
</li>
)}
</ul>
</div>
);
}
}

upload image file from react to nodejs

This is react code
import React, { Component } from "react";
import Webcam from "react-webcam";
import * as faceapi from "face-api.js";
import { browserHistory } from "react-router";
import axios from "axios";
export default class WebCamPicure extends Component {
constructor() {
super();
this.state = {
selectedFile: null
};
fileSelectedHandler = (event) => {
console.log(event.target.files[0]);
this.setState({
selectedFile: event.target.files[0]
});
};
fileUploadHandler = () => {
const fd = new FormData();
fd.append("image", this.state.selectedFile, this.state.selectedFile.name);
fetch("http://localhost:5000/upload", {
method: "POST",
headers: { "Content-Type": "multipart/form-data" },
mode: "no-cors",
body: fd
});
};
render() {
return (
<div
className="App"
style={{
display: "flex",
flexDirection: "column",
alignItems: "center"
}}
>
<div class="upload">
<input type="file" onChange={this.fileSelectedHandler} />
<button onClick={this.fileUploadHandler}>upload</button>
</div>
</div>
);
}
}
this is node server code
const express = require("express");
var mysql = require("mysql");
const axios = require("axios");
var connection = mysql.createConnection({
host: "localhost",
user: "root",
password: "",
database: "expression_detection"
});
connection.connect((err) => {
if (!!err) {
console.log("error");
} else {
console.log("connected");
}
});
const app = express();
app.get("/api/customers", (req, res) => {
const customer = [
{ id: 1, firstname: "jhon", lastname: "doe" },
{ id: 2, firstname: "praveen", lastname: "smith" },
{ id: 3, firstname: "kumar", lastname: "swason" }
];
res.json(customer);
});
app.get("/", (req, res) => {
connection.query("SELECT * FROM individual_result", (error, row, fields) => {
if (!!error) {
console.log("Error in the query");
} else {
console.log("seccessful query");
console.log(row);
}
});
res.json("hello");
});
app.post("/upload", (req, file, res) => {
console.log("got it");
console.log(req);
// console.log(res);
});
const port = 5000;
app.listen(port, () => {
console.log("server started on port " + port);
});
I am trying upload image to nodejs server but i not able to recevie the upload file in server.I uploaded my code above please help me to solve this.now i need to get the uploaded file in server and store in database
I am trying upload image to nodejs server but i not able to recevie the upload file in server.I uploaded my code above please help me to solve this.now i need to get the uploaded file in server and store in database
You will need to configure a dedicated handler to work with multipart/form-data.
You can use multer.
Multer is a node.js middleware for handling multipart/form-data, which is primarily used for uploading files.

How to submit multipart/form-data from react to express?

I'm trying to submit a form with an Image & Name of Category. But in my ExpressJS (backend) I'm unable to fetch the data. In express I'm using express-fileupload package. Below is my code, please help me to come out from this problem.
Front End (React - CategoryForm.js)
import axios from "axios";
import React, { Component } from "react";
class CategoryForm extends Component {
constructor(props) {
super(props);
this.state = { name: '', file: '', fileName: '' };
this.onChange = this.onChange.bind(this);
this.onChangeImageHandler = this.onChangeImageHandler.bind(this);
this.onCreate = this.onCreate.bind(this);
}
/** Methods */
onChange = e => this.setState({ [e.target.name]: e.target.value });
onChangeImageHandler = e => this.setState({ fileName: e.target.files[0].name, file: e.target.files[0] });
onCreate = async e => {
e.preventDefault();
e.stopPropagation();
const formData = new FormData();
formData.append('name', this.state.name);
formData.append('file', this.state.file);
const url = 'http://localhost:4000/api/v2/categories';
const token = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjVkZTc3MDM0NTgxM2QyN2NmZDExMWE3ZSIsImVtYWlsIjoiaGFyc2hhQHNrcmVlbS5pbyIsImlhdCI6MTU3NTQ0ODc1OSwiZXhwIjoxNTc2MzEyNzU5fQ.7wxCmPhkzb0aaB4q9PBKmHAj1Klw1NQmp1nBI3NsRRI';
axios({
method: 'POST',
url: url,
headers: {
Authorization: `Bearer ${token}`,
ContentType: 'multipart/form-data'
},
body: formData
})
.then(res => this.setState({ name: '', file: '', fileName: '' }))
.catch(err => console.log('Error - ', err));
}
/** Rendering the Template */
render() {
const { name, fileName } = this.state;
return (
<form onSubmit={this.onCreate}>
<input type="text" name="name" value={name} onChange={this.onChange} placeholder="New Category Name" />
<input type="file" name="file" onChange={this.onChangeImageHandler} />
<button type="submit">Add Category</button>
</form>
)
}
}
export default CategoryForm;
Back End (ExpressJS : server.js)
const express = require("express");
const bodyParser = require("body-parser");
const fileUpload = require("express-fileupload");
app.use(fileUpload());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use('/api/v2/categories',
(req, res, next) => { console.log(req.body); },
require("./categoryRoute"));
In req.body I'm getting { }. Please tell me How can send Image with Text data to express.
Note : If I'm passing only data (Not Image) from react, let say data: {name: 'Shivam'} then I'm getting it in backend.
React:
convert your media file to base64 string.
Express Js:
In express convert base64 to image(img,pdf,xlxs,etc...)
var base64Data = req.body.file_data // base64 string
var file_name='123.png';
var file_dir = "assets/client_folios/"
var fs = require("fs");
if (!fs.existsSync('assets/')){
fs.mkdirSync('assets/');
}
if (!fs.existsSync(file_dir)){
fs.mkdirSync(file_dir);
}
var file_path="assets/client_folios/"+file_name
var file_path="assets/client_folios/"+file_name
fs.writeFile(file_path, base64Data, 'base64',async function(err) {
}

POST http://localhost:3000/api/signup/ 404 (Not Found)

i am trying to send data of the user from react to express and use the create function to create a new user
but is says error 404 and page not found
why?
my api endpoint (found in client/src/components/api-users :
async function create (data) {
try {
const resp = await fetch('/api/signup/' , { //error initiating here
method:'POST',
mode:"cors",
credentials:'include',
headers:{
'Content-Type': 'application/json ',
'Accept': 'application/json',
"Access-Control-Origin": "*"
},
body:JSON.stringify(data)
})
console.log(resp)
console.log(resp.body)
resp.headers.forEach(console.log);
return JSON.stringify(resp);
} catch (err) {
console.log(err)
}
}
export {
create
}
my user controller for signup:
var jwt = require('jsonwebtoken');
var atob =require('atob')
var Cryptr = require('cryptr')
var cryptr = new Cryptr('q1w2e3r4t5y6u7i8o9p0p0o9i8u6y5t4r3e2w1q')
var db =require('../server')
const create = (req, res, next) =>{
first_name = req.body.first_name,
last_name = req.body.last_name,
username =req.body.username,
password= req.body.password,
email=req.body.email,
dec_pass =atob(toString(req.body.password)),
encrypted_pass =cryptr.encrypt(dec_pass)
var sql = "INSERT INTO `user`(`user_id`,`first_name`,`last_name`,`username` , `email`,`password`) VALUES ('','" + first_name + "','" + last_name + "','" + username + "','" +email+ "','" +encrypted_pass+ "')";
var query = db.query(sql, function(err, result){
console.log(query)
console.log(req)
return (JSON.stringify(result));
});
};
export
{ create }
server js file for db connection:
var Sequelize = require('sequelize')
var app = require('./app')
var CONFIG= require('../config/CONFIG')
const db = {}
const sequelize = new Sequelize ("users" , "root" , "" ,{
host:'localhost',
dialect:'mysql',
operatorAliases:false,
pool:{
max:5,
min:0,
acquire:30000,
idle:10000
}
})
console.log(CONFIG.db_host)
db.sequelize=sequelize
db.Sequelize=Sequelize
console.log('alright')
export default db
mu user routes :
const express = require('express');
const router = express.Router();
var userCtrl = require ('../controllers/user.controller')
router.post('/signup', userCtrl.create)
module.exports = router
my signupjs react file
import React, {Component} from 'react'
import {create} from './api-user.js'
class SignUp extends Component {
constructor(){
super();
this.state = {
username:'',
first_name:'',
last_name :'',
email : '',
password :''
}
this.clickSubmit = this.clickSubmit.bind(this)
}
componentWillReceiveProps(nextProps) {
console.log("nextProps", nextProps);
}
componentDidMount(){
console.log("Component did mount")
}
handleChange = e => {
if (e.target.name === "username") {
this.setState({ username: e.target.value });
}
if (e.target.name === "first_name") {
this.setState({ first_name: e.target.value });
}
if (e.target.name === "last_name") {
this.setState({ last_name: e.target.value });
}
if (e.target.name === "email") {
this.setState({ email: e.target.value });
} if (e.target.name === "password") {
this.setState({ password: e.target.value });
}
}
clickSubmit = (e) => {
e.preventDefault()
const data = this.setState({
first_name :this.state.first_name,
last_name : this.state.last_name,
username : this.state.username,
password:this.state.password,
email:this.state.email,
})
create(data) //i dnt know if this correct or not
}
As #Deep Kakkar mentioned you don't set an api prefix so you should find /signup working instead of /api/signup
also fetch(/api/signup) will hit this relative path on your current domain (where react app is up on), you need to set full path instead, for instance, if your http-server is up on port 4000 and your react app is up on 3000 then you should fetch http://localhost:4000/api/signup not /api/signup as this will be http://localhost:3000/api/signup
Localhost:3000/api/products 404 Error
You did not create res.get("/api/products") on server.js or you did not set the proxy. check below for proxy setting.
Proxy error: could not proxy request /api/products
Check this:
frontend/package.json
{
"name": "frontend",
"proxy": "http://127.0.0.1:5000",
...
}
stop running frontend and backend
Run backend first
npm start
Then frontend
cd frontend
npm start

Making POST request to SQL Server through React

I am trying to make a simple textbox entry form for the user to type their first and last name, then click submit. I'd like the data to be updated in my SQL Server. Whenever I try to make a request I get the error
Unexpected token S in JSON at position 0
This is the code I am using:
server.js:
var express = require('express');
var app = express();
var sql = require("mssql");
var config = {
user: 'username',
password: 'password',
server: 'localhost',
database: 'Master'
};
app.post('/', function(req, res) {
res.set('Access-Control-Allow-Origin', '*');
var user = req.body;
var connection = new sql.ConnectionPool(config, function(err) {
var request = new sql.Request(connection);
request.query('INSERT INTO Persons SET ?', user);
});
res.end('Success');
});
app.listen(5000, () => {console.log('Server is running..')});
And here is the code from react:
import React, { Component } from 'react';
class postData extends Component {
constructor() {
super();
this.state = { user: {} };
this.onSubmit = this.handleSubmit.bind(this);
}
handleSubmit(e) {
e.preventDefault();
var self = this;
// On submit of the form, send a POST request with the data to the server.
fetch('http://localhost:5000', {
method: 'POST',
data: {
FirstName: self.refs.FirstName,
LastName: self.refs.LastName
}
})
.then(function(response) {
//this is the line that is giving me the error
return response.json()
}).then(function(body) {
console.log(body);
});
}
render() {
return (
<form onSubmit={this.onSubmit}>
<input type="text" placeholder="First Name" ref="FirstName"/>
<input type="text" placeholder="Last Name" ref="LastName"/>
<input type="submit" />
</form>
);
}
}
export default postData;
I am getting the error from the react side. Not sure how to set this up. Any ideas where I might be screwing up? Thanks!!!
The data that your react app is passing to express is just the raw text. Try adding body-parser to your express app, and then deconstructing the values that are passed in. You could manually parse the body into JSON format, but it would be much easier to include body-parser. body-parser also allows you to parse the body of your request into other formats as well if you wish.
Add body-parser to your express app:
const bodyParser = require('body-parser');
app.use(bodyParser.json());
Then in your POST request, deconstruct the body like like this:
const { firstName, lastName } = req.body;
let connection = new sql.ConnectionPool(config, function(err) {
let request = new sql.Request(connection);
request.query(/* Your query to insert these values */);
});
res.end('Success');
Usually, you get that error because the response is a string instead of a JSON object. Try changing your express:
res.send({ message: 'Success'})
I'n not sure that you're using refs correctly either. I might try putting those values in state with an on change function:
handleChange = (e) => {
this.setState(
{
[e.target.name]: e.target.value
}
)
}
And change your inputs to:
<input type="text" placeholder="First Name" name="FirstName" onChange={this.handleChange}/>
Then in your submit function:
FirstName: this.state.FirstName
Hope that helps

Resources