Empty data in response with axios and vuex - axios

When I send this patch request with axios, the backend receives the data, but response.data comes back empty. Please and thanks!
// ACTION IN VUEX STORE
async updateMe({ commit }, payload) {
let id = localStorage.getItem('userId');
let user = { name: payload.name, email: payload.email, id: id };
try {
const response = await axios.patch(
`http://localhost:3000/api/v1/users/updateMe`,
user
);
commit('setUpdatedUser', response.data);
} catch (err) {
console.log(err);
}
}
// CONTROLLER
exports.updateMe = catchAsync(async (req, res, next) => {
const updatedUser = await User.findByIdAndUpdate(
req.body.id,
{
name: req.body.name,
email: req.body.email
},
{ new: true, runValidators: true }
);
res.status(204).json({ data: updatedUser });
});

204 is a No Content response code.

Related

How to update nested array in mongoDB using express

I need to update nested array 'commentLikes' in mongodb using nodejs. I have tried like this but not helped.
My Collection is this
_id: 6368f9cd1d1ae931a66de06e
userId: "625400bc00575a0301756870"
desc: "helloooooooo..."
location: ""
taggedFriends: Array
edited: false
likes: Array
dislikes: Array
comments: Array
0: Object
1: Object
commentId: "0.9418743386578314"
dp: "pic1.jpg"
name: "Mohammad Ashraf"
id: "625400bc00575a0301756870"
comment: "avvdvd jhuygjhgd"
commentLikes: Array
nestedComments: Array
and I want to update commentLikes, And I have try like one
//like comment
router.put("/:id/comment/:commentId/like", async (req, res) => {
try {
const post = await Post.findById(req.params.id);
const comment = await post.comments.find((cmnt)=>cmnt.commentId===req.params.commentId);
if (!comment.commentLikes.includes(req.body.userId)) {
// await comment.updateOne({$push: {commentLikes: req.body.userId}});
await post.updateOne({"comments.commentId": req.params.commentId}, {$push: {"comments.$.commentLikes": req.body.userId}});
res.status(200).json("The comment has been liked");
} else {
// await comment.updateOne({ $pull: { commentLikes: req.body.userId } }); // toggle
res.status(200).json("like removed");
}
} catch (err) {
res.status(500).json(err);
}
});
please help
exports.postComments = catchAsync(async (req, res, next) => {
const comment = req.body;
const blogId = req.params.blogId;
if (
!Object.keys(comment).length != 0 ||
!Object.getPrototypeOf(comment) === Object.prototype ||
!ObjectId.isValid(comment?.userId)
) {
return res.status(400).json({
response,
success: false,
message: "invalid request for comments",
});
// console.log("hello");
}
const response = await Blog.updateOne(
{ _id: blogId },
{
$push: { comments: comment },
}
);
if (response.modifiedCount <= 0) {
return res.status(200).json({
response,
success: false,
message: "can not insert new comment please try again",
});
}
res.status(200).json({
response,
success: false,
message: "can not insert new comment please try again",
});
// console.log(response);
});
or you can ask me for more question
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-html -->
exports.postComments = catchAsync(async (req, res, next) => {
const comment = req.body;
const blogId = req.params.blogId;
if (
!Object.keys(comment).length != 0 ||
!Object.getPrototypeOf(comment) === Object.prototype ||
!ObjectId.isValid(comment?.userId)
) {
return res.status(400).json({
response,
success: false,
message: "invalid request for comments",
});
// console.log("hello");
}
const response = await Blog.updateOne(
{ _id: blogId },
{
$push: { comments: comment },
}
);
if (response.modifiedCount <= 0) {
return res.status(200).json({
response,
success: false,
message: "can not insert new comment please try again",
});
}
res.status(200).json({
response,
success: false,
message: "can not insert new comment please try again",
});enter code here
// console.log(response);
});

How to get signed in users data?

I have a MERN mobile app thats using passportjs to authenticate and login users (with mongodb database and axios), however, when i eventually get to the the screen to enter in data (a "log"), i cant associate that data/log with the signed in user. How can i grab the user id several screens later after they have already signed in to associate it with the entry? My mongodb database has a number of users, so i only want a specific user's data (eg calories), ie the one that is currently logged in:
// Mongoose schemas
// log.model.js
const Schema = mongoose.Schema;
const logSchema = new Schema(
{
user: {
type: mongoose.Schema.Types.ObjectId,
ref: "User",
},
calories: {
type: Number,
required: true,
},
},
{
timestamps: true,
}
);
const Log = mongoose.model("Log", logSchema);
// user.model.js
const userSchema = new Schema(
{
_id: Schema.Types.ObjectId, // user id
email: {
type: String,
required: true,
unique: true,
trim: true,
},
password: {
type: String,
required: true,
trim: true,
minlength: 6,
},
},
{
timestamps: true,
}
);
const User = mongoose.model("User", userSchema);
They are first prompted to signin in the app, where they will then navigate to Home. Not all features are added in yet, just in development stage now:
// ./frontend/screens/signin.js
function onLoginPress() {
axios({
method: "POST",
data: {
email: email,
password: password,
},
withCredentials: true,
url: 'http:localhost:5000/users/signin',
})
.then((res) => console.log(res.data))
.catch((error) =>
console.log("ERROR: Promise rejected (sign in): " + error)
);
navigation.navigate("Home");
}
// ./backend/routes/users.js
router.route("/signin").post((req, res, next) => {
passport.authenticate("local", (error, user, info) => {
if (error) {
res.json({
status: "FAILED",
message: error,
});
}
if (!user) {
res.json({
status: "FAILED",
message: "No user exists",
});
} else {
req.logIn(user, (error) => {
if (error) console.log("ERROR: " + error);
res.json({
status: "SUCCESS",
message: "Successfully authenticated",
});
console.log(req.user);
});
}
})(req, res, next);
});
After they sign in, and they wish to enter in calories, i attempt to associate that log (and any future logs they might add) with the signed in user when they hit a button:
// ./frontend/screens/log.js
const [calories, setCalories] = React.useState("");
function onSaveLog() {
axios({
method: "post",
url: "http://localhost:5000/log/add",
data: {
calories: calories,
// CANT GET USER ID HERE?
},
})
.then((res) => {
console.log(res.data);
})
.catch(function () {
console.log("LOG ERROR: promise rejected");
});
}
// ./backend/routes/log.js
router.route("/add").post((req, res) => {
const calories = Number(req.body.calories);
// const user = req.body.user; // CANT GET THE USER ID HERE
const newLog = new Log({
calories,
// user,
});
// saves Log data to mongodb
newLog
.save()
.then(() => res.json("Log added"))
.catch((err) => res.status(400).json("Error: " + err));
});
so, what you doubt is, correct me if I'm wrong is that you want an ID that can be accessed somewhere later in the app to retrieve the users' data.
There are many ways to achieve that,
after you get the id, you can pass it as Navparams. check this for more info RN- params
Next you can store the id in async storage and retrieve it anywhere, I would suggest this cause is the easiest rn--async storage
import AsyncStorage from '#react-native-async-storage/async-storage';
const storeData = async (value) => {
try {
await AsyncStorage.setItem('#storage_Key', value)
} catch (e) {
// saving error
}
}
// read
const getData = async () => {
try {
const value = await AsyncStorage.getItem('#storage_Key')
if(value !== null) {
// value previously stored
}
} catch(e) {
// error reading value
}
}
you can do it this way, do tell me if you're stuck

findByIdAndUpdate do not update document

I am trying to update a field to the document with findByIdAndUpdate. The field I am trying to update is defined in the Bar Model. And I can also assure that req.body.bookId has a valid id.
Here's how my request looks,
app.patch("/foo", async (req, res) => {
try {
await validateId(req.body.bookId);
let doc = await Bar.findByIdAndUpdate(
req.body.bookId,
{ DateT: Date.now() },
{ new: true }
);
res.send(doc);
} catch (err) {
console.log(err);
}
});
Bar schema,
const mongoose = require("mongoose");
const barSchema = mongoose.Schema({
bookId: {
type: String,
unique: true,
},
DateT: {
type: Date,
default: null,
},
});
module.exports = mongoose.model("Bar", barSchema);
use updateOne, when you use async don't use .then() use try/catch
test it:
app.patch("/foo", async (req, res) => {
try {
let doc = await Bar.updateOne(
{ bookId : req.body.bookId },
{ DateT: Date.now() },
{ new: true }
);
res.send(doc);
} catch (error) {
console.log(error);
}
});
app.patch("/foo", async (req, res) => {
await Bar.findByIdAndUpdate(
req.body.bookId,
{ DateT: Date.now()},
(err, docs) => {
if (err) {
console.log(err);
} else {
res.send(docs);
}
}
);
});

Update email only if it doesn't already exist in mongoDB database

I'm using this route to allow a user to change their email address. However, it currently lets them add an email address that is already used by another user. How can I prevent this (and send an alert in this situation). Also, I'm wondering if .findOneAndUpdate() is appropriate here as it may stop after finding the first one.
Thanks
app.post('/changeUserEmail', function (req, res) {
db.collection("userDB").findOneAndUpdate(
{username: req.user.username},
{ $set: {email: req.body.newEmail}},
{new: true},
(err, data) => {
if (err) {
console.log(err);
}
console.log(null, data);
}
)
res.render(process.cwd() + "/views/options", {
username: req.user.username,
email: req.body.newEmail,
alert: "Email changed"
});
});
You could first check if the email exists before you update something
app.post("/changeUserEmail", async function(req, res) {
let { username } = req.user;
let { newEmail } = req.body;
let emailExist = await db.collection("userDB").findOne({ email: newEmail });
if (emailExist)
return res.render(process.cwd() + "/views/options", {
alert: "Email already exists"
});
await db
.collection("userDB")
.findOneAndUpdate(
{ username },
{ $set: { email: newEmail } },
{ new: true }
);
res.render(process.cwd() + "/views/options", {
username,
email,
alert: "Email changed"
});
});

Mongoose model not persisting object

In a nutshell, I'm working on a math assessment app that takes your answers and stores them in a database and I'm having trouble adding more than one object to the backend. The Mongoose model is as such:
const mongoose = require('mongoose');
const Algebra1Schema = new mongoose.Schema({
user: {
type: mongoose.Schema.Types.ObjectId,
ref: 'user'
},
answers: {
type: Object
},
date: {
type: Date,
default: Date.now
}
})
module.exports = algebra1 = mongoose.model('algebra1', Algebra1Schema)
Here is the route:
// Submit application/json parser
var jsonParser = bodyParser.json();
router.post('/', [jsonParser, auth], async (req, res) => {
try {
let newTest = new algebra1({
answers: req.body,
user: req.user.id
})
await newTest.save();
res.json(req.body);
} catch (err) {
console.error(err.message);
res.status(500).send('Server error');
}
})
module.exports = router;
Here is the update action that makes an axios POST request:
export const submit = (results, history) => async dispatch => {
try {
const config = {
headers: {
'Content-Type': 'application/json'
}
}
const res = await axios.post('/api/algebra1', results, config);
// dispatch({
// type: QuestionActionTypes.RESET
// })
dispatch(setAlert('You\;ve finished your assessment!', 'success'));
history.push('/results');
} catch (err) {
console.error(err.message);
// dispatch({
// type: PROFILE_ERROR,
// payload: { msg: err.response.statusText, status: err.response.status }
// })
}
}
I want to add a percentage item to the algebra1 model, that looks like this:
const Algebra1Schema = new mongoose.Schema({
user: {
type: mongoose.Schema.Types.ObjectId,
ref: 'user'
},
answers: {
type: Object
},
**percent:{
type: Number**
date: {
type: Date,
default: Date.now
}
})
When I changed the route to have a percent Number added, the request goes to the database, but the answers object and percent Number aren't included. I tried updating the route to:
let newTest = new algebra1({
answers: req.body.answers,
percent: req.body.percent
user: req.user.id
})
I tried adding the following before the axios POST request:
const body = JSON.stringify({ results, percent });
and using body in place of results in the axios POST request, but the same result; nothing was persisted to the database except the user.
Any ideas as to what I'm doing wrong? I thought maybe the results object I'm sending in my action isn't correct, but when I only send the answers as req.body, it goes through and the database has the answers object.