Reactjs: post data to localhost always pending - node.js

I am working on ReactJs and NodeJS and I am creating a signup page. I post data to server but it is always pending.
Which part did I do wrong? It would be nice if someone can help.
Front end:
const handleSubmit = (event) => {
// prevent page refresh
event.preventDefault();
const newUserData = {
name: name,
email: email,
password: password,
};
axios
.post("/signup", newUserData)
.then((res) => {
console.log(res.data);
})
.catch((error) => {
console.log(error);
});
setEmail("");
setName("");
setPassword("")
console.log("form submitted ✅");
};
Backend:
router.post("/signup", (req, res) => {
const { name, email, password } = req.body;
if (!email || !password || !name) {
res.status(422).send({ error: "Please add all the fields" });
}
console.log(req.body);
User.findOne({ email: email })
.then((savedUser) => {
if (savedUser) {
res.status(422).send({ error: "Email already been used" });
}
bcrypt.hash(password, 12).then((hashedpassword) => {
const user = new User({
name,
email,
password: hashedpassword,
});
user
.save()
.then((user) => {
res.json({ message: "Sign Up Successfully" });
})
.catch((err) => {
console.log(err);
});
});
})
.catch((err) => {
console.log(err);
});
});
in package.json i set proxy as
"proxy": "http://localhost:5000",

I guess you are using MongoDB as well, in that case keep in your mind that the findOne is async, so you need to use await before. And for to save data you need to use the .create() method from MongoDB, e.g.
router.post("/signup", async (req, res) => {
const { name, email, password } = req.body;
if (!email || !password || !name) {
res.status(422).send({ error: "Please add all the fields" });
}
console.log(req.body);
await User.findOne({ email: email })
.then((savedUser) => {
if (savedUser) {
// you need to add return to stop the code
return res.status(422).send({ error: "Email already been used" });
}
// or you can add else because the code keep running
bcrypt.hash(password, 12).then((hashedpassword) => {
const user = await User.create({
name,
email,
password: hashedpassword,
});
user
.save()
.then((user) => {
res.json({ message: "Sign Up Successfully" });
})
.catch((err) => {
console.log(err);
});
});
})
.catch((err) => {
console.log(err);
});
});
I think it is better to use something like throw new Error('Email already been used') instead of return for your res.status(422).send({ error: "Email already been used" }); because if you have return the server doesn't give back an error, but a normal answer, but of course it is ok if you want that.

I want you to be sure that before you submit, the values name, email, password, are updated. Please try:
const handleSubmit = async (event) => {
// prevent page refresh
event.preventDefault();
console.log(`The value for the name: ${name}`);
console.log(`The value for the email: ${email}`);
console.log(`The value for the password: ${password}`);
try {
const response = await axios.post("http://localhost:5000/signup", {
name,
email,
password,
});
console.log(response.data);
setEmail("");
setName("");
setPassword("");
console.log("form submitted ✅");
} catch (error) {
console.log(error);
}
};

Related

Not able to send post request to my express API

I am sending a post request to my Heroku API, but receiving nothing in return.
This is where I am making the request:
const [ user, setUser] = useState({
email:"",
password:""
})
const handleChange = e => {
const { name, value } = e.target
setUser({
...user,
[name]: value
})
}
const login = () => {
axios.post("https://<myherokuapp>/login", user)
.then(res => {
alert(res.data.message)
setLoginUser(res.data.user)
navigate("/")
})
}
This is the body of the request:
app.post("/login", (req, res)=> {
const { email, password} = req.body
User.findOne({ email: email}, (err, user) => {
if(user){
if(password === user.password ) {
res.send({message: "Login Successfull", user: user})
} else {
res.send({ message: "Password didn't match"})
}
} else {
res.send({message: "User not registered"})
}
})
})
app.post("/register", (req, res)=> {
const { name, email, password} = req.body
User.findOne({email: email}, (err, user) => {
if(user){
res.send({message: "User already registerd"})
} else {
const user = new User({
name,
email,
password
})
user.save(err => {
if(err) {
res.send(err)
} else {
res.send( { message: "Successfully Registered, Please login now." })
}
})
}
})
})
This is the index.js running on heroku:
import express from "express"
import cors from "cors"
import mongoose from "mongoose"
const app = express();
const port = process.env.PORT || 9002;
app.use(express.json())
app.use(express.urlencoded())
app.use(cors())
mongoose.connect("mongodb+srv://<myDbLink>.mongodb.net/?retryWrites=true&w=majority", {
useNewUrlParser: true,
useUnifiedTopology: true
}, () => {
console.log("DB connected")
})
const userSchema = new mongoose.Schema({
name: String,
email: String,
password: String
})
const User = new mongoose.model("User", userSchema)
//Routes
app.post("/login", (req, res)=> {
const { email, password} = req.body
User.findOne({ email: email}, (err, user) => {
if(user){
if(password === user.password ) {
res.send({message: "Login Successfull", user: user})
} else {
res.send({ message: "Password didn't match"})
}
} else {
res.send({message: "User not registered"})
}
})
})
app.post("/register", (req, res)=> {
const { name, email, password} = req.body
User.findOne({email: email}, (err, user) => {
if(user){
res.send({message: "User already registerd"})
} else {
const user = new User({
name,
email,
password
})
user.save(err => {
if(err) {
res.send(err)
} else {
res.send( { message: "Successfully Registered, Please login now." })
}
})
}
})
})
app.get("/",(req,res)=>{
res.send("get is working")
})
app.listen(port,() => {
console.log("BE started at port")
})
When I tried in my localhost , it was working fine , but now it is giving me an error user is not registered , even when I have the user in my database. Please help me solve this problem , this is the first time I am using heroku with nodejs.
Your route code is correct but the approach of hosting a website on Heroku is wrong, you should need to connect DB with Atlas Cluster for more detail and follow up on the official documentation Host Website on Heroku that uses Mongodb

How to save the Reset Password Nodejs and MongoDb

I am using SendGrid to send the user the reset password link that goes with two parameters (The user._id and token). I have another component that saves the user's changed the password but all I get is an error user. save is not a function
Email helper Code.
import sendGrid from "#sendgrid/mail";
export class sendGridEmail {
static async sendResetPasswordEmail(email, token, id) {
sendGrid.setApiKey(process.env.SENDGRID_API_KEY);
const msg = {
to: `${email}`,
from: `${process.env.VERIFIED_SENDER}`, // Change to your verified sender
subject: "RESET YOUR PASSWORD",
text: `Follow this link to reset your password: ${process.env.BASE_URL}/${id}/${token}`,
};
return sendGrid
.send(msg)
.then(() => {
console.log(`password rest link has been sent to: ${email}`);
})
.catch((err) => {
console.log(err);
});
}
sendLink Component
export const resetUserPassword = asynchandler(async (req, res) => {
const { email } = req.body;
const user = await userModel.findOne({ email });
if (!user) {
res.status(404);
res.json({ message: "the email provided was not found" });
} else if (user) {
const token = AuthToken(user._id);
try {
await sendGridEmail.sendResetPasswordEmail(user.email, token, user._id);
res.status(200);
res.json({
message: `a link to reset your password has been sent to: ${user.email}`,
});
} catch (error) {
res.status(500);
res.json({ message: error });
}
} else {
res.status(500);
res.json({ message: "Internal Server Error" });
}
});
The Component that tries to update the password in the Database but I get an error user.save() is not a function
export const saveResetPassword = asynchandler(async (req, res) => {
const { id, authorization } = req.params;
const user = userModel.findOne(req.params.id);
const private_key=process.env.PRIVATE_KEY
const payload = jwt.verify(authorization, private_key);
if (user._id === id || payload.id) {
try {
user.password = req.body.password;
await user.save();
} catch (error) {
res.status(404);
res.json({ message: `an error occured: ${error}` });
}
}else{
res.status(500)
res.json({message: "an error occured"})
}
});
My Routes
import { loginUser, registerUser, resetUserPassword, saveResetPassword } from "./controllers/user.controller.js";
export const Routes =(app)=>{
app.get("/health", (req,res) => {
res.send(200).json({message:"Server health check is Ok"});
});
// user api's
app.post('/api/registeruser', registerUser);
app.post('/api/loginuser', loginUser);
app.post('/api/password-reset', resetUserPassword);
app.post("/api/save-password/:id/:authorization", saveResetPassword);
}
const user = await userModel.findOne(req.params.id);
You forgot await, model.findOne() returns a Promise

vue.js | TypeError: Cannot read property 'then' of undefined

I'm trying to make email verification in my vue.js/express app.
I can create the user and send emails. But showing a message like "verification mail sent" won't work.
The error occurs when executing the code in the then() callback after the execution in DataService.
When registering the following functions are executed:
vuex
const actions = {
registerUser({
commit
}, user) {
commit('registerRequest', user)
return DataService.registerUser(JSON.stringify(user))
// HERE'S THE ERROR
.then(response => {
commit('confirmation', response.message)
setTimeout(() => {
state.status = {
confirmHere: ''
}
}, 4000);
})
.catch(...)
confirmation:
confirmation: (state, msg) => {
state.status = {
confirmHere: msg
}
},
DataService
registerUser(user) {
// Send email for registration
apiClient.post('/user/register/sendMail', user)
.then(res => {
return apiClient.post(`/user/register`, user)
})
.catch(err => {
throw err;
})
},
The sendmail function is using nodemailer to send an email and returns
res.status(200).json({
message: "success"
});
The register function in express is:
router.post('/register', async (req, res) => {
try {
if (req.body.username !== undefined && req.body.password !== undefined) {
let password = await bcrypt.hashSync(req.body.password, saltRounds);
let compareUser = await db.getObject({}, User, 'SELECT * FROM app_users WHERE username=? LIMIT 1', [req.body.username]);
if (compareUser !== undefined) {
res.status(409).json('User already exists');
return;
}
const tmp = {
username: req.body.username,
password: password
};
await db.query('INSERT INTO app_users SET ?', [tmp]);
let user = await db.getObject({}, User, 'SELECT * FROM app_users WHERE username=? LIMIT 1', [req.body.username]);
if (user === undefined)
res.status(500).json('Internal server error');
res.status(201).json({
"message": "Bestätigungs-Email gesendet."
});
} else {
res.sendStatus(400);
}
} catch (error) {
res.sendStatus(500);
}
});
You forgot to return the response from DataService.registerUser
// DataService.js
registerUser(user) {
// Send email for registration
return apiClient.post('/user/register/sendMail', user)
.then(res => {
return apiClient.post(`/user/register`, user)
})
.catch(err => {
throw err;
})
The issue is that your registerUser function doesn't return anything whereas you're expecting it to return a promise.
Change your registerUser to:
registerUser(user) {
// Send email for registration
return apiClient.post('/user/register/sendMail', user)
.then(res => {
return apiClient.post(`/user/register`, user)
})
}
(FYI in the example, I left the .throw out because it already gets handled by the Promise you return ;)

How to display errors with Axios in React

Good day,
i am running to a slight problem with Axios, i want to check if the status code is ok, if not then i send the error to the client. How can i do that ?
This is my attempt to do it, but i had no success:
Route code:
router.post("/register", async (req, res) => {
try {
//check if fields are empty
const { name, email, password, rePassword } = req.body;
if (!name || !email || !password || !rePassword) {
return res.status(406).send("fields are empty");
}
//passsword length should be at leats 6 characters
if (password.length < 6) {
return res
.status(406)
.send("Password should at least be 6 characters long");
}
//checking if passwords match
if (password !== rePassword) {
return res.status(406).send("Passwords dont match");
}
//check if user exists
const emailExist = await User.findOne({ email: req.body.email });
if (emailExist) {
return res.status(406).send("User already exists");
} else {
//create salt
const salt = await genSalt(10);
//hashing the password
const hashedPassword = await hash(req.body.password, salt);
const user = new User({
name: req.body.name,
email: req.body.email,
password: hashedPassword,
isAdmin: req.body.isAdmin,
});
const newUser = await user.save();
res.status(200).send(newUser);
}
} catch (err) {
console.log(err);
}
});
Page code:
const handleSubmit = async e => {
e.preventDefault();
axios
.post("http://localhost:5000/users/register", {
name,
email,
password,
rePassword,
})
.then(response => {
console.log(response.data);
})
.catch(err => {
console.log(err);
});
}
The response will give you the following options
console.log(response.data);
console.log(response.status);
console.log(response.statusText);
console.log(response.headers);
console.log(response.config);
This will allow you to check for valid stausText/codes, or display errors accordingly.

Invalid email or password

don't know whats going on wrong,when i am trying to post request through postman i am getting an error like "Invalid email or password". in sign in. please help
signup
below is my signup request where i am doing my signup validation.
const User = require('../model/user');
const bcrypt = require('bcryptjs');
exports.signup = (req, res) => {
const { name, email, password } = req.body;
if (!name || !email || !password) {
res.status(422).json({
error: "please add all field"
})
}
User.findOne({ email: email })
.then((SavedUser) => {
if (SavedUser) {
return res.status(400).json({
error: "User already exists that email"
})
}
const user = new User({
email,
password,
name
})
user.save()
.then(user => {
res.json({
message: "saved Successfully"
})
.catch(err => {
console.log(err);
})
})
.catch(err => {
console.log(err);
})
})
}
Signin
below is my signin form where i doing my signin operation
exports.signin = (req, res) => {
const { email, password } = req.body;
if (!email || !password) {
res.status(422).json({
error: "please enter email and password"
})
}
User.findOne({ email: email })
.then(SavedUser => {
if (!SavedUser) {
return res.status(400).json({
error: "invalid email or password"
})
}
bcrypt.compare(password, SavedUser.password)
.then(doMatch => {
if (doMatch) {
res.json({
message: "Successfully Signed in"
})
}
else {
return res.status(422).json({
error: "Invalid email or password"
})
}
})
.catch(err => {
console.log(err);
})
})
}
It seems you're not hasing the password, when creating a new mongoose user-object. Obvioulsy, bcrypt.compare(password, SavedUser.password) will then fail. Try to do it like this (note I'm using async/await here instead of promises directly):
password = await bcrypt.hash(password, 10);
const user = new User({
email,
password,
name
});
you didn't bcrypt your password at the time of saving.
You can make a pre save function in your schema like this.
// Hash the plain text password before saving
User.pre("save", async function (next) {
const user = this;
try {
if (user.isModified("password")) {
user.password = await bcrypt.hash(user.password, 8);
}
next();
} catch (error) {
next(error);
}
});

Resources