req.users undefined react express - node.js

so im getting an undefined response when fetching my api and i really dont know why
this is the function calls in the component
const init = usersId => {
getUser(usersId).then(data => {
if (data.error) {
setValues({ ...values, error: data.error });
} else {
// populate the state
setValues({
...values,
username: data.username,
email: data.email,
formData: new FormData()
});
}
});
};
this is the api call in react
export const getUser = usersId => {
console.log('ok')
console.log(usersId)
return fetch(`${API}/users/${usersId}`, {
method: 'GET'
})
.then(response => {
return response.json();
})
.catch(err => console.log(err));
};
at this point im getting the user id correctly but when the fetch is running i get an error that i cant read property of undefined so, there is the express server endpoint
router.get('/users/:usersId',
read_);
and here is the controller
userCtrl.read_ = (req, res) => {
console.log(req.users)
console.log('test')
return res.json(req.users);
};
i really dont know what im doing wrong at this point

You can't get req.user, cos you're not sending req.user.
You are only sending userId and you can only get it via req.params
like this
req.params.userId
What you want to do is use the userId to get the associated user from your DB

if you want req.user you'll have to find user from id.
you can get id by req.params.userId
after getting userdata from database assign user object to req.user
like this: req.user = user;
then you can access req.user

Related

Node JS : How to retrive data from frontend after a res.json(data) in backend?

my backend send a res.staus(200).json({somedata)} to my front, but i can't retrieve the data in the frontend.
My backend :
exports.login = (req, res, next) => {
//===== Check if user exists in DB ======
const { user_email, user_password: clearPassword } = req.body;
let sql = `SELECT user_password, user_id FROM users WHERE user_email=?`;
db.query(sql, [user_email], async (err, results) => {
console.log(results);
console.log(req.body);
if (err) {
return res.status(404).json({ err });
}
// ===== Verify password with hash in DB ======
const { user_password: hashedPassword, user_id } = results[0];
try {
const match = await bcrypt.compare(clearPassword, hashedPassword);
if (match) {
console.log("match ... user_id : ", user_id);
// If match, generate JWT token
res.status(200).json({
test: 'iyu',
user_id: user_id,
token: jwt.sign({ userId: user_id }, "TOOOKEN", {
expiresIn: "24h",
}),
});
} else {
console.log("not match");
}
} catch (err) {
return res.status(400).json({ err: "une erreur" });
}
});
};
The frontend :
const login = async (e) => {
e.preventDefault();
await POST(ENDPOINTS.USER_LOGIN, userLogin);
// await GET(ENDPOINTS.USER_LOGIN)
fetch("http://localhost:4200/api/auth/login")
.then((response) => response.json())
.then((data) => {
console.log(data);
});
};
This login fonction send data to my backend, then the backend checks if an user exist in database with the first POST request. If yes, the backend send in json format some data that i wan't to put in the local storage of the user, so after the POST request, i do another request with GET method to retrieve the json data sent from the back, but i have an 404 error.
How can i get my data sent by the back ?
Seems the problem is with the SQL statement, underneath the if statement you have can you print the error like so:
if(err) {
console.log(err);
}
and tell me the result please

findById request, cant find my data in mongodb collection

I am creating URL Shortener Microservice application.I have a mongodb cluster that i save my all url links. I am successfully connect to database.I am making post request to save my posted url. Related code is here
app.post('/api/shorturl', (req, res) => {
const bodyUrl = req.body.url;
const something = dns.lookup(
urlParser.parse(bodyUrl).hostname,
(error, address) => {
if (!address) {
res.json({ error: 'Invalid URL' });
} else {
const url = new Url({ url: bodyUrl });
url.save((err, data) => {
res.json({
original_url: data.url,
short_url: data.id,
});
});
}
}
);
});
So, I can save my new url in database succesfully.Here also related cluster after post request
But my problem is with get request. I dont know why i cant find the url links by id. Here also my get request
app.get('/api/shorturl/:id', (req, res) => {
// const id = req.body.id;
Url.findById({ _id: req.body.id }, (err, data) => {
if (!data) {
res.json({ error: 'Invalid URL' });
} else {
res.redirect(data.url);
}
});
});
You need to either use:
Url.findOne({ _id: req.params.id }, (err, data) => {
if (!data) {
res.json({ error: 'Invalid URL' });
} else {
res.redirect(data.url);
}
});
or:
Url.findById(req.params.id, (err, data) => {
if (!data) {
res.json({ error: 'Invalid URL' });
} else {
res.redirect(data.url);
}
});
findOne takes an object as the argument (like you have).
findById just takes the ID as the argument.
You seem to be combining the two options.
Edit: I found another issue with your code, you are trying to pull the id from req.body.id, but in this case, you need to use req.params.id. The code in my post has been updated.

Why mongo query is showing undefined in node js

I'm trying to check the data with findOne when im trying with the postman getting undefined in console.log , i checked with the same query in roboMongo and its showing the data
this is the result:-
Here is the code:-
exports.signIn = async( req, res ) => {
const {
userEmailPhone,
} = req.body;
await User.findOne ({ email : userEmailPhone}).then((err, user)=> {
console.log("user..", user)
if (user){
res.status(200).send({
message: "sucess"
});
}
})
}
the postman response:-
Since you are already using async - await, I believe there is no need of using the .then() block.
Your code should be updated to use async and await as below:
exports.signIn = async( req, res ) => {
const { email } = req.body;
const user = await User.findOne ({ email : userEmailPhone})
console.log("user..", user)
if (user){
res.status(200).send({
message: "sucess"
});
}
}
If you still want to use the .then() block, I would recommend making the following changes in the code:
exports.signIn = async ( req, res ) => {
const {email} = req.body;
User.findOne ({ email : email}).then((user, err)=> {
console.log("user..", user)
if (user){
res.status(200).send({
message: "sucess"
});
}
})
}
Since the promise callback for MongoDb queries has the following callback format:
.then( (res, err) => {
// do stuff
})
Reference : https://docs.mongodb.com/drivers/node/fundamentals/promises/
You are sending raw json data. First you should use app.use(bodyParser.json());. Only app.use(bodyParser()); is deprecated.
This should fix it assuming you have a json body-parser
exports.signIn = async( req, res ) => {
const {email} = req.body;
User.findOne ({ email : email}).then((err, user)=> {
console.log("user..", user)
if (user){
res.status(200).send({
message: "sucess"
});
}
})
}

Handling Server-Side Errors on React: Formik & Yup

I've been trying to handle error from serverside (i.e. email already exists)
Summary of what I have tried so far:
Asynchronously create User Model with email being unique field upon POST /register request.
If there's an Error, I will send client side an error using "res.send(e)".
await Axios request saving it to variable response under try.
On the catch block, set error to field with name 'email'
Finally set submitting to false so user can fix the error.
Result: No console.log or error message from the server.
My questions are as follows:
How do I specify which error I am getting from server-side? (I've tried console logging error blocks by trying to access "e.detail" but I will get undefined.
How to handle this on client side using Formik and Yup? (What's the best practice?)
Below are my code set up.
My server router setup.
const handleErrors = (e) => {
console.log(Object.values(e));
res.send(e)
};
module.exports.register_post = async (req, res) => {
const { email, password, name, gender, social, about, interests } = req.body;
try {
const user = await User.create({
email,
password,
name,
gender,
twitter: social.twitter,
instagram: social.instagram,
about,
interests,
});
const token = createToken(user.id);
console.log(user);
res.cookie('jwt', token, { httpOnly: true, maxAge: maxAge * 1000 });
res.send(user);
} catch (e) {
handleErrors(e);
}
};
My Front-End React(with Formik) side set up
const onSubmit = async (values, { setSubmitting, setFieldError }) => {
const filteredValues = _pickBy(values, (_, key) => key !== 'password2');
try {
const response = await axios.post('http://localhost:8080/register', {
...filteredValues,
});
console.log(response);
history.push('/register/verification');
} catch (e) {
setFieldError('email', e);
} finally {
setSubmitting(false);
}
};

How to get error object on client side from node.js backend?

I'm having a little issue. I'm developing an app and I created API with node.js(using express). Right now I'm trying to send my error objects from node to react but for some reason I cannot get it. I can see the object in the network tab but I want to use it, like console it to the client.
back-end:
app.post('/api/users/login', async (req, res) => {
try {
const user = await User.findByCredentials({ ...req.body });
const token = await user.generateAuthToken();
res
.cookie('w_auth', token)
.status(200)
.send({ user, token });
} catch (error) {
res.status(400).send({ success: false, error: 'some error' });
}
});
client-side:
loginUser:
export const loginUser = dataToSubmit => {
return axios.post(`${USER_SERVER}/login`, dataToSubmit);
};
loginUser(dataToSubmit)
.then(res => {
console.log(res);
dispatch({ type: 'SET_USER', user: res.data.user });
})
.catch(error => {
console.log(error);
});
I tried also just send a respond without error from back-end which also didn't work.
picture of what I get:
network tab:
You can catch it the below way.
axios
.post(url, data)
.then(response => {
//You get success response here.
})
.catch(err => {
//Error response here
});

Resources