Axios post request not working React Nodejs Mongodb - node.js

I am trying to post a data to the mongoose database but I keep getting Axios error 404. I need help. Is there something wrong in my code?
This is my modal, it contains the front end of the website
AddForm.jsx
import React, { useState } from "react";
import axios, { Axios } from "axios";
const AddForm = () =>{
const [appData, setAppData] = useState({
pName:"",
appNum:"",
datetime:"",
})
const submit =(e) =>{
e.preventDefault();
axios.post("/addAppDetails", {
pName: appData.pName,
appNum: appData.appNum,
datetime: appData.datetime,
})
.then(res =>{
console.log(res.appData)
})
.catch((error)=>{
console.log(error);
});
}
const handle = (e) => {
const newData={...appData}
newData[e.target.id] = e.target.value
setAppData(newData)
console.log(newData)
}
return(
<Form onSubmit={(e) => submit(e)}>
<Form.Group>
<Form.Control
id="pName"
type="text"
placeholder="Patient Name"
onChange={(e) => handle(e)}
value={appData.pName}
required/>
</Form.Group>
<Form.Group>
<Form.Control
id="appNum"
type="text"
placeholder="Appointment Number"
onChange={(e) => handle(e)}
required/>
</Form.Group>
<Form.Group>
<Form.Control
id="datetime"
as="textarea"
placeholder="Date and Time"
onChange={(e) => handle(e)}
required/>
</Form.Group>
<Button variant="success" type="submit" block>Update Appointment</Button>
</Form>
)
}
export default AddForm;
This is my backend, it contains the route/api for functionality
server.js
const express = require("express");
const app = express();
const mongoose = require("mongoose");
const cors = require("cors");
const bcrypt = require("bcryptjs");
const jwt = require("jsonwebtoken");
app.use(express.json()); //prints body request
app.use(cors());
const JWT_SECRET = "sdaikdhjiIHDiu8987J(#?!dDSF8645DAsadA[]ds54aASD()21asd1SFP";
const mongooseURL =
"mongodb+srv://client:lolpassword#cluster0.lfrgaha.mongodb.net/?retryWrites=true&w=majority";
//server
app.listen(5001, () => {
console.log("Server started successfully.");
});
//connect with DB
mongoose
.connect(mongooseURL, {
useNewUrlParser: true,
})
.then(() => {
console.log("Connected to database successfully");
})
.catch((e) => console.log(e));
require("./models/appointmentDetails");
const AppDetails = mongoose.model("AppointmentDetails");
//add data to db
app.post("/addAppDetails", async(req, res) => {
const newAppDetails = new AppDetails(req.body);
try{
newAppDetails.save();
res.send(newAppDetails);
}
catch(err){
console.log(err);
res.status(500).send(error);
}
});
This is my database model.
appointmentDetails.js
const AppDetails = new mongoose.Schema(
{
pName: String,
appNum: String,
datetime: String,
status: String,
action: String,
},
{
collection: "AppointmentDetails",
}
);
mongoose.model("AppointmentDetails", AppDetails);

404 means the url (including http://host:port) that you are using to send request & expecting response from, doesn't exist in your case.
While sending request, check if your node server is receiving the response or not, using logs, or a global middleware function logging every request info. This way you'll see whether the server is receiving the request or not, and thus find the problem.
As suggested in the answer by #thillon (now deleted probably), most likely in your case the url is incomplete (doesn't contain the server's host:port part), so you can follow their way to ensure that your request url is proper and thus make sure that your server is able to receive request is this particular case.
Global middleware function
Write this right after your app.use(express.json()) statement.
app.use((req, res, next) => {
console.log(req.body)
// or log anything helpful in the req object
next();
})

Related

I want to tell reactjs login component whether login was successful or not

I am confused as to how to communicate from the nodejs server to the reactjs login component on whether login was successful or not.
I have a reactjs component that handles login as follows:
Login.js
import React, {useState} from 'react';
import axios from "axios";
const Login = () => {
const [user,setUser] = useState({email:"",password:""});
const handleSubmit = (e) => {
e.preventDefault();
console.log(user);
axios.post('http://localhost:5000/login',user)
.then(function (response) {
console.log(response);
console.log("Successfully done");
})
.catch(function (error) {
console.log("error here")
console.log(error.message);
});
}
return (
<div>
<h1>Login</h1>
<form onSubmit={handleSubmit}>
<div>Email:</div>
<div><input type="text" name="email" placeholder='Enter your email'
onChange={(e)=>setUser({...user,email:e.target.value})}
/></div>
<div>Password:</div>
<div><input type="password" name="password" placeholder='Enter your password'
onChange={(e)=>setUser({...user,password:e.target.value})}
/></div>
<div><input type="submit" value="Add" /></div>
</form>
</div>
)
}
export default Login;
and an expressjs backed that processes the login
server.js
const express = require("express");
const mongoose = require("mongoose");
const User = require("./Models/Conn.js");
const bcrypt = require("bcryptjs");
//const Route1 = require("./Routes/Route.js");
const cors = require('cors');
const app = express();
//app.use("/api",Route1);
app.use(express.json({extended:true}));
app.use(express.urlencoded({extended:true}));
app.use(cors());
const url = "mongodb+srv://pekele:pekele#cluster0.yqaef.mongodb.net/myDatabase?retryWrites=true&w=majority";
mongoose.connect(url)
.then(()=>console.log("connected to database successfully"))
.catch(err=>console.log(err));
app.get("/",(req,res)=> {
res.send("<h1>Welcome Guest</h1>");
});
app.get("/signup",(req,res)=> {
res.json({"id":"1"});
})
app.post("/signup",(req,res)=> {
const {email,password} = req.body;
bcrypt.genSalt(10)
.then(salt=> {
bcrypt.hash(password,salt)
.then(hash => {
const user = new User({email,password:hash});
user.save()
.then(()=>console.log("Successfully saved"))
.catch(error=>console.log(error));
})
}).catch(err=>console.log(err));
})
app.post("/login",(req,res)=> {
const {email,password} = req.body;
console.log(`My email is ${email}`)
User.findOne({email:email}, function (err, doc) {
console.log(doc);
if(doc == null) {
//How do i let react login page know that there is no user with such email
}
if(doc != null) {
const emailDB = doc.email;
const passwordDB = doc.password;
bcrypt.compare(password,passwordDB)
.then(res => {
//How do I tell the react login page that the login was successful
}).catch(err=>console.log(err));
}
});
})
app.listen(5000,()=> console.log("Server listening on port 5000"));
The problem is how do I communicate to the react login page whether the login was successful or not in the app.post("/login",(req,res) ... Thanks
You can send data via -
res.json(data)
res.send("Submitted Successfully!")
res.status(200).send(message)

Post request sends null value to the database POSTGRESQL react node

When I am making a post request from react, it sends a null value to the database.
So, I put log statements everywhere and it seems that : on the server side in nodejs, the const {firstName} is undefined and I do not understand why. Also, I log the req on the server-side and the body is empty body:{}.
Client side: when I put log statement in try block on body, it log me this: firstName: "abc" . So, the POST method does receive the body, but I do not understand where it gets lost?
When I console.log the state, it does set the state to the input value. However, when it sends data, the value is null.
I am using the following Reactjs, Nodejs, aws-rds-postgresql.
This is sever-side in nodejs
app.post("/users", async (req, res) => {
try {
const {firstName} = req.body;
console.log({firstName})
const newUser = await pool.query(
"INSERT INTO users (firstname) VALUES ($1) RETURNING *",
[firstName]
);
res.json(newUser.rows[0]);
}catch (err) {
console.log(err.message);
}
});
This is client side in react:
const CreateEmployee = (props) => {
const [firstName, setEmployeeForm] = useState("");
const onSubmitForm = async (event) => {
event.preventDefault();
try {
const body = {firstName};
console.log(body);
const response = await fetch("http://localhost:5000/users", {
method: "POST",
headers: {"Content-Type": "application/json"},
// We convert the React state to JSON and send it as the POST body
body: JSON.stringify(body)
});
console.log(response);
} catch (err) {
console.log(err.message);
}
}
return (
<Fragment>
<h1 className="text-center mt-5">PernTodo</h1>
<form className="d-flex mt-5" onSubmit={onSubmitForm}>
<input type="text" className="form-control" value={firstName} onChange={e=> setEmployeeForm(e.target.value)}/>
<button className="btn btn-success">Add</button>
</form>
</Fragment>
);
}
export default CreateEmployee;
I found the answer.
The issue was with the order of body-parser;
The order must be as follows with bodyParser on the very top.
const bodyParser = require('body-parser');
const express = require("express");
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: false}));
Adding this line in nodejs worked for me:
app.use(express.json())

why does it not update the sql row in the react web application?

I am building a web application by using react, axios as front end, and sqlite, express, nodejs as the back end.
I am trying to search a student from the server and database, and then modify the name of the student. However, although I made sure my backend should be alright by using postman, it still does not update the row I selected. And I also made sure the object I passed to the server is an object containing only studentId and firstName by using console.log.
This is my react javascript
It has two main function:
handleSearch: Search the student by using the searchId from the user
handleModifyFirstName: Modify the student first name based on the studentId, and this is the function that does not work.
import React, { useState } from "react";
import axios from "axios";
const SearchStudent = () => {
const [searchId, setSearchId] = useState("");
const [studentsList, setStudentsList] = useState([]);
const [firstName, setFirstName] = useState("");
const handleSearch = () => {
const newSearchId = searchId;
axios
.get("http://localhost:8080/students/" + newSearchId)
.then((response) => {
setStudentsList(response.data.row);
});
setSearchId("");
setStudentsList([]);
};
const handleModifyFirstName = (studentId) => {
const data = { studentId, firstName };
window.alert(data);
console.log(data);
axios
.post("http://localhost:8080/students/modifyFirstName/", data)
.then((response) => {
var resData = response.data;
let data = JSON.stringify(resData);
window.alert("Response recieved from server = " + data);
});
};
return (
<div>
<form>
<input
type="text"
id="searchId"
name="searchId"
value={searchId}
onChange={(e) => setSearchId(e.target.value)}
></input>
</form>
<button onClick={handleSearch}>search</button>
{studentsList.map((data) => (
<div key={data.studentId}>
<h4>first Name: {data.firstName}</h4>
<p>second name: {data.lastName}</p>
<input
type="text"
id="firstName"
name="firstName"
value={firstName}
onChange={(e) => setFirstName(e.target.value)}
></input>
<button onClick={() => handleModifyFirstName(data.studentId)}>
edit first name
</button>
</div>
))}
</div>
);
};
export default SearchStudent;
This is the server.js
var express = require("express");
var cors = require("cors");
var bodyParser = require("body-parser");
var db = require("./database.js");
var app = express();
app.use(cors());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
var HTTP_PORT = 8080;
app.listen(HTTP_PORT, () => {
console.log("Server running on port %PORT%".replace("%PORT%", HTTP_PORT));
});
app.get("/", (req, res, next) => {
res.json({ message: "Ok" });
});
app.post("/students/modifyFirstName/", (req, res, next) => {
//this is the SQL query that should work
const sql = 'UPDATE students SET firstName =? WHERE studentId =?';
const params = [req.query["firstName"], req.query["studentId"]];
// const params = [data.firstName, data.studentId];
db.run(sql, params, function (err, result) {
if (err) {
res.status(400).json({ error: err.message });
return;
}
res.json({
message: "success",
data: data,
id: this.lastID,
});
});
});
This is the database.js
var sqlite3 = require("sqlite3").verbose();
let db = new sqlite3.Database("students.db", (err) => {
if (err) {
console.error(err.message);
throw err;
}
console.log("Connected to the students database.");
});
const sql =
"CREATE TABLE students (firstName text, lastName text, studentId text) ";
db.run(sql, (err) => {
if (err) {
console.log("Table already created.");
} else {
console.log("Table created.");
console.log("First time Table created, creating some rows.");
var insert =
"INSERT INTO students (firstName, lastName, studentId) VALUES(?,?,?)";
db.run(insert, ["hellow", "world1", "1"]);
db.run(insert, ["hellow", "world2", "2"]);
db.run(insert, ["some", "value", "3"]);
}
});
module.exports = db;
Any help would be appreciated!
In the server.js file you should be using req.body because you are sending a JSON object. req.query is used for the query string within the URL.
const params = [req.body["firstName"], req.body["studentId"]];

req.files is undefined using express-fileupload

I am creating a blog so, wanted to upload an image for each post. I used express-file upload for this purpose. Using nodejs I have done the following to save the image sent from the client-side in MongoDB. When I print the value of req.files in the console I get undefined.
exports.addPost = (req, res) => {
const file = req.files.file
const post = new Blog()
post.title = req.body.title
post.des = req.body.des
post.file = file
post.save((err, doc) => {
if (!err) {
res.send(doc)
} else {
console.log(err)
}
})
}
In react I have Addpost.js that sets the state and handles the form submit as follows:
const Addpost=()=> {
const [title, settitle] = useState('')
const [des, setdes] = useState('')
const [file, setfile] = useState('');
const {addPost}=useContext(Globalcontext)
const handleSubmit = (e)=>{
e.preventDefault()
const formData = new FormData()
formData.append('file',file)
const addedValue={
title,
des,
formData
}
addPost(addedValue)
settitle('')
setdes('')
setfile('')
}
const onChange=(e)=>{
const file=e.target.files[0]
setfile(file)
}
return (
<div>
<form onSubmit={handleSubmit} encType="multipart/form-data">
<input type="text" name="title" value={title} onChange={(e)=>settitle(e.target.value)}/>
<input type="text" name="des"value={des} onChange={(e)=>setdes(e.target.value)}/>
<input type="file" name="file" onChange={onChange}/>
<button type='submit' value='submit'>Add Post</button>
</form>
</div>
)
}
The AXIOS post request is sent as:
function addPost(postdetail) {
axios.post('http://localhost:4000/blog', postdetail).then(res => {
dispatch({
type: 'ADD_DATA',
payload: res.data
})
}).catch(error => {
console.log(error)
})
}
I am getting the error:
Cannot read property 'file' of undefined
1. Probably you didn't register middleware.
According to the doc example, you should register express-fileupload middleware before you refer req.files:
const express = require('express');
const fileUpload = require('express-fileupload');
const app = express();
// default options
app.use(fileUpload());
Also don't forget to add null check in case when no files are uploaded:
app.post('/upload', function(req, res) {
if (!req.files || Object.keys(req.files).length === 0) {
return res.status(400).send('No files were uploaded.');
}
let file = req.files.file;
// do something with uploaded temp file
}
2. Content type should be multipart/form-data when you upload file
const handleSubmit=(e)=>{
e.preventDefault()
const formData=new FormData()
formData.append('file', file)
setfile('')
}
function addPost(postdetail){
axios.post('http://localhost:4000/blog',formData, {
headers: {
'Content-Type': 'multipart/form-data'
}
}).then(res=>{
dispatch({
type:'ADD_DATA',
payload:res.data
})
}).catch(error=>{
console.log(error)
})
}
3. Other form fields(des, title) may not be submitted using multipart/formdata
Consider open two routes for blog creation.
[POST] '/blog/upload-image' for image upload
[POST] '/blog/new for create blog (title, des and image_id acquired from image upload response)

Unable to show response message from node server

I am creating MERN stack app and trying to save data in database.After data added successfully in database I am sending success message from node server and I want to show this message on front-end side but it is showing nothing though I am sending message from server.
Below is my code:
React code form.js
import React,{Component} from 'react';
import Axios from 'axios';
import swal from 'sweetalert';
class Form extends Component{
constructor(props){
super(props)
this.state = {
title:'',
detail:''
}
}
onTitleChange = (e) => {
this.setState({
title:e.target.value
});
}
onDetailChange = (e) => {
this.setState({
detail:e.target.value
});
}
handleSubmit = (e) => {
e.preventDefault();
Axios.post('http://localhost:5000/save',{
title:this.state.title,
detail:this.state.detail
}).then((msg) =>{
swal(msg);
}).catch((err) => {
console.log("React Error:",err);
});
}
render(){
return(
<div className="container">
<h2 id="formTitle">Add blog</h2>
<form>
<div>
<input type="text" className="validate" name="title" value={this.state.title} placeholder="Title" onChange={this.onTitleChange} required/>
</div>
<div>
<textarea type="text" value={this.state.detail} className="validate materialize-textarea" name="detail" placeholder="Detail" onChange={this.onDetailChange} required></textarea>
</div>
SUBMIT
</form>
</div>
)
}
};
export default Form;
saveData.js
const express = require('express');
const router = express.Router();
const bodyParser = require('body-parser');
const blogs = require('../models/blogPost');
const mongoose = require('mongoose');
router.use(bodyParser.json());
router.use(bodyParser.urlencoded({extended: true}));
const dburl = 'mongodb+srv://exp#cluster1-5ws.mongodb.net/expdb?retryWrites=true'
router.post('/save',(req,res) => {
const data = {
title: req.body.title,
detail: req.body.detail
}
const newBlog = new blogs(data);
mongoose.connect(dburl, {useNewUrlParser: true,useUnifiedTopology:true}).then((resp) =>{
newBlog.save().then(() => {
res.json({msg:"Data inserted"});
}).catch((err) => {
console.log("Insertion error", err);
});
}).catch((err) => {
console.log("database error: ",err);
});
});
module.exports = router;
mongoose database schema blogPost.js
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const BlogPostSchema = new Schema({
title:String,
detail:String,
date:{
type:String,
dafault:Date.now()
}
});
const BlogPost = mongoose.model('BlogPost',BlogPostSchema);
module.exports = BlogPost;
Someone please let me know what I m doing wrong any help would be appreciated.
Thanks
In Axios then block Simply add res.data to get response from server.
Axios.post('http://localhost:5000/save',{
title:this.state.title,
detail:this.state.detail
}).then((res) =>{
swal(res.data);
}).catch((err) => {
console.log("React Error:",err);
});
THANKS

Resources