axios is not implementing post request - node.js

i am trying to post data with axios (NodeJS, ReactJS) but i ended up getting this errors
and here is my posting code
axios({
method: 'post',
url: '/api/signup',
data:
{
username: this.state.username,
name: this.state.name,
surname: this.state.surname,
email: this.state.email,
password: this.state.password,
confirm_password: this.state.confirm_password,
}
})
.then(res => res.data)
.then(url => window.location.href = url.location)
.catch(error => this.setState({errorBol: true, errorMessage: error}))
and my nodeJS code
router.post('/', async (req,res)=>{
const username = req.body.username;
const name = req.body.name;
const surname = req.body.surname;
const email = req.body.email;
const password = req.body.password;
const confirm_password = req.body.confirm_password;
console.log(username)
console.log(name)
console.log(surname)
console.log(email)
console.log(password)
console.log(confirm_password)
res.status(200).send({location: '/'})
})
i have config for /api/signup like this
router.use('/api/main', require('./sinupfilename'))
so problem is not in router.post('/')
about problem:
i am implementing post request form submission and have a validation for form and it works perfectly but it gives me an errors above when i click submit button so if anyone know clue, i will be glad to hear it

Looks like the issue is not with axios but with your render function. The above issue comes when you are trying to render any object instead of a valid react element.
The issue might be at setState for errorMessage variable. Try printing the errorMessage or typeof errorMessage for further info. It should not be an object.
The error is an javascript object if you read the official documentation for axios.
You need to extract the error message and set it in your errorMessage variable. It should work fine. As per the docs, the same can be done is this similar manner:
const err = ""
if (error.response) {
err = error.response.data
} else if (error.request) {
err = error.request.response
} else {
err = error.message
}
this.setState({errorBol: true, errorMessage: err})
Basically, any thing which needs to be rendered has to be valid react element like string, html tags, numbers but not object. So, you need to make sure that whatever is rendered, it needs to be a valid react element. You can read more about it here
Hope it helps, revert for any doubts.

Related

postman (thunder client) can send request but axios cannot

I am trying to send http requests using axios to my node backend. For some reason, axios keeps returning a 500 (Internal Server Error) even when thunder client (dollar store version of postman) is able to send the request and get a proper response.
index.js (server)
app.get('/api/login', async (req, res) => {
try {
const user = await User.findOne({ email: req.body.email })
if(user===undefined) { res.status(404).json("user not found"); }
const validPassword = await bcrypt.compare(req.body.password, user.password)
!validPassword && res.status(400).json("wrong password")
res.status(200).json(user)
} catch (err) {
res.status(500).json(err)
}
})
Login.js (frontend)
const login = (email, password) => {
console.log(email + ': ' + password)
axios.get('http://localhost:8800/api/login', { email: email, password: password })
.then((response) => console.log(response))
.catch((err) => console.log(err.response))
}
err.response returns no useful data and err.response.data is a blank object. I've tried to edit the request header, but it is already 'application/json'. Again, this request works on thunder client and I made sure that the data I passed in was correct through the console.log(email + ': ' + password . I've been trying to fix this issue for hours so please help. Thank you in advance.
Update: I had previously binded the login function to an onClick to a button, but I put the axios function directly into the brackets instead of login(email, password). The issue persists.
Second Update: I followed the comments' advice and console logged the error on the terminal. It returned TypeError: Cannot read properties of null (reading 'password'). This was strange because in the function, I had console logged password and it returned the proper text. It also says that it cannot find a user within my database that uses the email I am currently using, but even when I pass in the exact email I use in thunder client requests, I still get the error. I think the data is not getting there properly.
Third Update: My hypothesis is confirmed. In index.js, I made the route console log req.body.email and it returned undefined. I passed in an object that I JSON stringified and when console logged in the browser, it returns a proper object. The request is sending an object with undefined properties although I am passing in an object with values
In this case, the issue was that the request was a get request, not a post request. Get requests do not take in data while post requests do. Here is the fix:
index.js (server)
app.post('/api/login', async (req, res) => {
try {
const user = await User.findOne({ email: req.body.email })
if(user===undefined) { res.status(404).json("user not found"); }
const validPassword = await bcrypt.compare(req.body.password, user.password)
!validPassword && res.status(400).json("wrong password")
res.status(200).json(user)
} catch (err) {
res.status(500).json(err)
}
})
If you have to receive the request parameters in body (mainly in json format) then you have to go with POST type request.
In the GET type request, you can get request parameters in the form of params and query string.
Parameters may be either part of path:
myapi/customers/123
or a query string:
myapi?customer=123
More details can be found here:
https://www.restapitutorial.com/lessons/httpmethods.html

Sending data from expressjs request to form

I have a login system where a user enters their information and when they submit it I validate the info with express and if it is not valid i send an error message. Right now i'm just using res.send for the error message, how would i go about redirecting back to my form but having an error message with it. I would prefer not to use url parameters because that is not secure.
So what I understand, is that you want your login form, that show the error message e.g. the password is wrong.
const login = (req, res) => {
const user = new userModel(req.body.email, req.body.password);
const found = db.findUser(user);
if (found) {
if (user.password == found.password) {
res.status(200).send(true);
} else {
res.status(401).json({ msg: 'The password is incorrect'});
}
} else {
res.status(404).send(false);
}
};
Then you could use the msg property is the password is wrong in the fetch.
fetch('/api/users/login', {
method: 'POST'
})
.then(res => res.json())
.then(data => {
document.getElementById('...some div').innerHTML = `<div>${data.msg}</div>`
})

Sending data from react to node by get request using axios library

for more than 3 hours I'm handling with an issue, what I'm trying to do is sending a get request from react to nodejs using axios library, I wanna pass some data into this request, as we know the get request don't have a body, so I've sent the data as query parameter like that
// base URL
const url = "http://localhost:8080/loginAsTeacher";
if(loginAs === "loginTeacher"){
axios.get(url,{
params :{
email: "abc123#gmail.com",
password: "abc1234*"
}
})
.then(res => console.log(res)) // this line return status:200 and data:null
.catch(err => console.log(err.message))
}
so this request success but the problem is the email and password are not passing to the backend
router.get("/loginAsTeacher", async (req,res)=>{
// values coming from the client
const loginEmail = req.params.email;
const loginPassword = req.params.password;
console.log(req.params); // this line return {} empty object
// get data of that user by his/her mail
const teacherData = await myModel.findOne({
email: loginEmail
}).exec()
res.status(200).json({
status: 200,
data: teacherData
})
})
the console.log above return an empty object, which means there's no parameters
Is this not the right solution ???
thanks for reading
To get your queries you need to get req.query instead of req.params
Btw. it's dangerous to send sensitive data over get. It could be get logged in plaintext even over https
use req.query instead of req.params. it will solve the issue

NODE/EXPRESS: [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client

I'm working on building an node/express backend and continue to receive the following error: (node:35061) UnhandledPromiseRejectionWarning: Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client. I'm not exactly sure what i am doing wrong here... Can someone educate me on what the issue might be? TIA!
Route
userRoutes.post('', async (req, res) => {
try {
const { email, password } = req.body;
const validate = await signUp.validate({ email, password });
res.send(validate);
const newUser = new User({ email, password });
const sessionUser = sessionizeUser(newUser);
await newUser.save();
req.session.user = sessionUser;
res.send(sessionUser);
return;
} catch (error) {
res.status(400).send(parseError(error));
}
});
The problem lies here in try block
try {
const { email, password } = req.body;
const validate = await signUp.validate({ email, password });
res.send(validate); //over here
const newUser = new User({ email, password });
const sessionUser = sessionizeUser(newUser);
await newUser.save();
req.session.user = sessionUser;
res.send(sessionUser); //over here
return;
}
this means is that for a given client request the server previously sent a response (either a success response with the resource requested or error response for a bad request) back to the client and now is unexpectedly trying to send another response
Solution
The simple fix for this error is to add javascript return statement to the response being sent from the if conditional to ensure that the request handler function exits(terminate) excuting code with the function once a response has being sent to the client.
The description for the return statement on MDN states
When a return statement is used in a function body, the execution of the function is stopped. If specified, a given value is returned to the function caller.

Validation with Joi in Axios call not giving correct response

I'm trying to apply validation with Joi on a NodeJS server and my frontend is Vue.
This is my backend validation function (in the AuthenticationPolicy):
register(req, res, next) {
const schema = Joi.object({
email: Joi.string().email(),
password: Joi.string().required()
})
const result = schema.validate(req.body)
if (result.error) {
console.log(`There was an error: ${JSON.stringify(result.error.details)}`)
res.status(400).send(JSON.stringify(result.error.details))
}
else {
next()
}
}
This is the hanlder for the registration:
var authenticationPolicy = require('./policies/AuthenticationPolicy')
router.post('/register', authenticationPolicy.register, (req, res, next) => {
console.log(`Entered registration on server after validation`)
res.send(`Registered! ${req.body.email}`)
})
When I try to enter an invalid Email the server logs:
There was an error: [{"message":"\"email\" must be a valid email","path":["email"],"type":"string.email","context":{"value":"Mailmailmail","key":"email","label":"email"}}]
POST /register 400 43.382 ms - 151
This is the relevant part in the frontend:
Service:
register(credentials) {
return Api().post('/register', credentials) //Api is the axios created to my baseURL
}
Method in component:
async register() {
try {
this.error = null;
await AuthenticationService.register({
email: this.email,
password: this.password
})
}
catch (err) {
console.log(`${err.message}`)
this.error = err.message
}
}
When I run this with an invalid Email (mailmail) the browser logs Request failed with status code 400. Why doesn't the err.message That I log on the front end match the response I get from the backend? If I understand correctly, Axios rejected the promise because of the 400 status so it was thrown, but where did the body go?
Thanks,
Ben
So after many hours of debugging and playing around, I realized that the err object that I catch is an object whose structure I didn't know. Specifically, it has a response component. err.response.data got me what I want.
I would still like to know if anyone has any ideas how could I find something like this out, I didn't see anything that pointed me in this direction in the documentation and I guess the logging wasn't what I expected.

Resources