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
Related
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
I am trying to set up a get route using axios. I am using React. I am trying to get the state of user.
user.user logs:
{_id: '62c5bdda933b818e12bef350', username: 'JordanF', Profiles: Array(9), createdAt: '2022-07-06T16:52:42.396Z', updatedAt: '2022-07-09T19:24:10.523Z', …}
I am trying to display username on my page. But at the moment I can't even log the username to my backend, so won't be able to search my db.
Profile.jsx
function getUser(data) {
console.log(data)
axios({
url: `http://localhost:3000/profiles`,
method: "GET",
data: data
})
.then((response) => console.log(response))
}
useEffect(() => {
setProfileList(profiles)
getUser(user.user)
},[]);
Data logs the data in the front end that I would like to get in the backend
BackEnd Controller
I have tried a lot of different syntax for this, this is my most recent. In the backend temrinal my console.log hits, and req.body returns an empty object.
async function getUser(req,res){
console.log('getUser hit')
function log(){
console.log(req.body)
return req.body
}
await log()
}
Yup! I was being silly. GET requests are only really concerned with params. I changed my route, so that the User's ID was in the URL path, and used req.params.id and everything worked out!
I'm stuck on this very simple problem and I don't know what I am doing wrong. I'm creating a simple RESTAPI with users and authentication. This is the GET request that I'm trying to run:
router.get('/users/me',auth ,async(req,res)=>{
console.log(req.user)
console.log('Entered the get request')
res.send(getUserData(req.user)) })
Basically, at the end of the authentication, I save the user fetched from the database into req.user object and then I send it to the client using res.send(req.user). As you can see in the code below:
const auth = async(req,res,next)=>{
try{
const token = req.header('Authorization').replace('Bearer ','')
const decoded = jwt.verify(token,'secretkey')
const db = req.app.locals.database
const user = await db.collection('users').findOne({
_id: decoded.id,
'tokens.token':token
})
console.log(user)
if(!user){
throw new Error()
}
req.user = user
next()
}catch(e){
res.status(401).send('Please Authenticate')
}}
The problem is that this authentication function is working perfectly fine. I have used it on other routes as well. But in this GET request, the authentication function runs (I identified this using many console logs) and fetches the data correctly. But it doesn't enter the get request once the middleware(auth function) has completed the call.
From POSTMAN, when I send GET requests, I get a 404 error and I have no idea why. I have literally spent hours trying to make sense of this. Please help me out if you know what might be the problem.
EDIT: So I was able to run the get request by moving the request above the following request that I also have in the same file:
router.get('/users/:id',auth ,async(req,res)=>{
const id = req.params.id
const db = req.app.locals.database
try{
const result = await db.collection('users').findOne({_id: id})
const userData = getUserData(result)
res.status(200).send(userData)
}catch(e){
res.status(404).send()
}
})
But now this request doesn't work. I cant figure out what positioning has to do with requests functionality. Can anyone please explain?
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.
this is my HTTP service right here :
postData(name, country) {
var body = JSON.stringify({
"name":name,
"country":country
});
console.log(name); // it outpus the correct value
console.log(country); // it outpus the correct value
return this.http.post('http://178.62.58.150:5000/api/cosmo/',body)
.map(res => {
res.text();
console.log(res.text());
})
.do(data => {
this.data = data;
// console.log(this.data);
})
}
It seems that it doesn't send the body to the POST request.
these output the correct value of the body
console.log(name);
console.log(country);
But
console.log(res.text());
It gives me a DB validation Error, which states that the body and country are required...
How do I send the body correctly?
P.S. : I tested this with POSTMAN and it works!
Looks like the issue is in building the post params, try
var body = JSON.stringify({
name: name,
country: country
})
Note that my hash keys are not strings, because stringify will convert a JavaScript object to a JSON string.
If this doesn't work, check with Google Developer tool on what your request is sending to the server.
I have added
let headers = new Headers();
headers.append("Content-Type","application/json");
return this.http.post('http://178.62.58.150:5000/api/cosmo/',body,{headers:headers})