Getting an empty object in Axios Get Request - node.js

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!

Related

How to use with credentials: true with TanStack Query fetch

Previously I used axios request withcredentials:true to get the cookie from server site when I started to to use useQuery of TanStack Query/react Query to fetch data, I couldn't be able to sent withCredentials: true. So I couldn't get any cookie from server site. Can anyone help me how to sent withCredentials when I'm fetching with useQuery of TanStack Query?
I have been tried to get answer that how to use React Query or TanStack query with Credentials.
React query doesn't perform any fetching, you can keep using axios.
const { data } = useQuery([some, key], async () => {
const { data } = await axios.get('SOME_URL', { withCredentials: true })
return data
}}

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 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

Calling users from angular to node (MEAN) is sending only email and _id to angular

I'm using the following code ..
// Node.js
router.get('/users/all', authenticate, (req, res) => {
User.find({some query}).select('firstName lastName email').then((users) => {
res.send(users);
});
//Angular Service
let opts = { headers: this.getCommonHeaders(), params: new HttpParams() };
return this.http.get(getUserDataUrl, opts)
.pipe(
map(response => {
// here is the problem
console.log(response.json());
return response.json()
}),
catchError(this.handleErrors)
);
In the opts headers I have mentioned the data type:
getCommonHeaders() {
return new HttpHeaders({
'Content-Type': 'application/json',
'x-auth': this.getToken()
})
}
In the console.log(response.json()) I'm getting only email and _id in the array's object. Adding the same console.log(user) on node.js before res.send(user) is showing the entire data with firstName and lastName
Then I added .lean() to the User function. this allowed the rest of the firstName and lastName to appear. How do I get the entire data without converting them to plain objects?
To me it seems like this is the problem. When you use find() method in mongoose, It gives an array. so you convert that array into json and send using res.send(). so when you access it using Angular. it may be crashing and not giving the correct format so try changing the code in node js like this.
Instead of find() try using findOne() in mongoose like this. I assume you only intend to take one user from this query right ?
// Node.js
router.get('/users/all', authenticate, (req, res) => {
User.findOne({some query}).select('firstName lastName email').then((user) => {
res.send(user); // there was a typo I changed it too. look in the question not user it was users.
});
Try to use res.json("JSON Object"); instead of res.send()..
Else try to check the db using tool like robomongo

Cant get all response data from fetch

So I'm trying to store some info in the session, for later use. But when I fetch it in react, it doesn't all come back. Despite the get route having all of the data.
My thought process is on the serverside, when a user logs in store their id in the session. I'll then have a /userinfo route that dumps all the data i need in json. I can then fetch that /userinfo route and get the data in the response. My code is as follows:
Heres the post code to sign in, I console.log to verify the session is modified. It is.
User.authenticate(req.body.logemail, req.body.logpassword, function (error, user) {
if (error || !user) {
var err = new Error('Wrong email or password.');
err.status = 401;
return next(err);
} else {
req.session.userId = user._id;
console.log(req.session);
return res.redirect('/');
}
});
Then I have this route:
app.get('/userinfo', (req, res)=>{
res.json(req.session);
});
If I simply go to localhost:3000/userinfo the json looks like:
{
"cookie": {
"originalMaxAge": null,
"expires": null,
"httpOnly": true,
"path": "/"
},
"userId": "blahblahblah"
}
so UserID is indeed there.
However, when I finally go to fetch it in react with:
fetch('http://localhost:3000/userinfo')
.then(res => res.json())
.then(data => console.log(data));
All I get back is the cookie. I dont get UserId. I've tried adding UserId to the cookie as well, just to see if it'd work, and likewise I just get the plain cookie.
Solved the issue myself, I didn't even think about it, but I'm making the request from the client, so when I make the request through fetch()
to
app.get('/userinfo', (req, res)=>{
res.json(req.session);
});
the server is returning the session stored on the clientside, which hasnt been updated with userId. So I need to return session data from the serverside, rather than from the client request.
My solution is to create and maintain a User object on the server-side and when I need to access user data, grab it from the user object.

Resources