Cannot set headers after they are sent to the client' - javascript

I am new to nodeJs but I already make research in order to solve my issue but it seems that I lacking a bit in async functionalities.
I have found this solution but it does not work which I will post it down below :
enter link description here
Here is my code
router.put("/placeOrder", [auth, isVerified, isExists], async (req, res) => {
try {
const productList = req.body; // body
await Promise.all(
productList.map(async (element) => {
// compare between the inserted element and the store one here
let getItemPrice = await Order.findOne({
_id: element._id,
buyerId: req.user._id,
orderStatus: "PENDING",
});
if (!getItemPrice) {
return res.status(400).json({
status: "failed",
message: "order not exists",
});
}
getItemPrice.items.map(async (item) => {
await Order.findOneAndUpdate(
{
"items.productId": item.productId,
},
{
$set: {
orderStatus: "ACTIVE",
"items.$.itemStatus": "ACTIVE",
paymentMethod: element.paymentMethod,
},
}
);
});
})
);
res.status(200).json({
message: "Order has placed",
});
} catch (error) {
return res.status(400).json({
status: "failed",
message: error.message,
});
}
// update documents
});
I am trying to check if the Id does not exist within my array if not exists just through an error that Id does not exist, it is working fine but it keeps print error to the logs that say:
TypeError: Cannot create property 'Symbol(level)' on string 'Cannot set headers after they are sent to the client'
Thanks for your time and collerations

You cannot send multiple responses.
productList.map(async (element, i) => {
// compare between the inserted element and the store one here
let getItemPrice = await Order.findOne({
_id: element._id,
buyerId: req.user._id,
orderStatus: "PENDING",
});
getItemPrice && getItemPrice.items.map(async (item) => {
await Order.findOneAndUpdate(
{
"items.productId": item.productId,
},
{
$set: {
orderStatus: "ACTIVE",
"items.$.itemStatus": "ACTIVE",
paymentMethod: element.paymentMethod,
},
}
);
});
}

Related

How to validate if my Purchase already has a Dispute or not. Purchase's Model has no disputes, but Dispute's has Purchase

How to validate if my Purchase already has a Dispute or not. Purchase's Model has no disputes, but Dispute's has Purchase. I'm using socket.io.
socket.on(
"new cause",
async (purchase, userId, msgCause, sellerId, callback, res) => {
if (!msgCause || msgCause === "") {
return callback({ error: true });
}
const disputeExist = await Dispute.findOne({ purchaseId: purchase }).populate({ path: 'purchaseId' }).lean();
var erros = [];
if ( purchase == disputeExist.purchaseId ) {
erros.push({ text: "Dispute already exist" });
}
if (erros.length > 0) {
res.render("user/chat", { erros });
} else {
const dispute = await new Dispute({
buyer: userId,
seller: sellerId,
purchaseId: purchase,
message: msgCause,
}).save();
if (!dispute) {
return callback({ error: true, message: "dispute save error" });
}
const user = await User.findOneAndUpdate(
{ _id: userId },
{ $push: { disputes: dispute._id } }
).lean();
if (!user) {
return callback({ error: true, message: "user save error" });
}
//io.to(purchase).emit("chat message", new Date().toLocaleString("en-us") + msgCause);
callback({ error: false });
}
}
);

Error in updating profile with image using mongoose and cloudinary

updateProfile: async function(req, res) {
try {
const update = req.body;
const id = req.params.id;
if (!req.files || Object.keys(req.files).length === 0) {
return res.status(400).send('No files were uploaded.');
}
const image = req.files.profileImage;
const cloudFile = await upload(image.tempFilePath);
const profileImage = cloudFile.url
console.log('Loging cloudfile', profileImage)
await User.updateOne(id, { update }, { profileImage }, { new: true },
function(err, doc) {
if (err) {
console.log(err)
}
if (doc) {
return res.status(200).send({ sucess: true, msg: 'Profile updated successful' })
}
});
} catch (error) {
res.status(500).json({ msg: error.message });
}
}
But I'm getting an error of "Callback must be a function, got [object Object]"
I have tried to $set: update and $set: profileImage but still not working.
So the image successful upload into the cloudinary but the update for mongoose is not working.
Upon brief research into the issue, I think you are feeding the arguments in wrong. Objects can be confusing but not to worry.
Your code is:
await User.updateOne(id, { update }, { profileImage }, { new: true }
However, I believe it should be something more like:
await User.updateOne({id: id}, { profileImagine: profileImage, new: true },
The API reference annotates use of the function as:
const filter = { name: 'John Doe' };
const update = { age: 30 };
const oldDocument = await User.updateOne(filter, update);
oldDocument.n; // Number of documents matched
oldDocument.nModified; // Number of documents modified

Why I still get the 200 response status code instead of 404?

I just making delete query to mysql with sequelize.
const model = require('../../../config/model/index');
const controller = {};
controller.drop = async function(req, res) {
try {
await model.activitys.destroy({
where: {
id: req.params.id
}
})
check_id = model.activitys.findAll({
where: {
id: req.params.id
}
})
if(check_id!=null){
res.status(200).json({
status: "Success",
message: "Success",
data: {}
})
}else{
res.status(404).json({
status: "Not Found",
message: `Activity with ID ${id} Not Found`,
data: {}
})
}
} catch (error) {
res.status(404).json({
status: "Error",
message: error.message
})
}
}
module.exports = controller;
I want to delete the data on DB from id parameters, it's work for deleting the data. But when I try to delete by id that not exist in my DB, it's still get the 200 status code.
How to make that will return 404 status code if there's no data exists in DB ?
If you want to check if a single record exists in DB then use findOne or findByPk instead of findAll. findAll always returns an array (either empty or not) and that means it's always not equal to null:
check_id = model.activitys.findOne({
where: {
id: req.params.id
}
})

Firebase get request returning empty array?

I believe it may just be an error in my logic, but i'm not sure where the problem is exactly and I am looking for help debugging. I am using Firebase Cloud Firestore. I am trying to query through my "follows" collection to return all data where the key "senderHandle" is equal to the params handle and then push that data to the empty array followData. Then, loop through each followData and make a document query call to the "posts" collection. Then, loop through each of the returned documents from the "posts" collection and push each data to the empty array "posts".
When I try to return the posts array though it returns empty. My overall goal is to get all of the users the params handle follows, loop through each user to get their posts, and then push their posts into an empty array.
Functions code:
// fetch home-specific posts (of users following)
exports.getHomePosts = (req, res) => {
let posts = [];
let followData = [];
// get following users
const followDocument = db
.collection("follows")
.where("senderHandle", "==", req.params.handle);
followDocument
.get()
.then((data) => {
if (data.query.size == 0) {
return res.status(400).json({ error: "Not following any users" });
} else {
data.forEach((doc) => {
followData.push(doc.data());
});
}
})
.then(() => {
followData.forEach((follow) => {
db.collection("posts")
.where("userHandle", "==", follow.receiverHandle)
.where("location", "==", "explore")
.get()
.then((data) => {
data.forEach((doc) => {
posts.push({
postId: doc.id,
body: doc.data().body,
userHandle: doc.data().userHandle,
createdAt: doc.data().createdAt,
commentCount: doc.data().commentCount,
likeCount: doc.data().likeCount,
userImage: doc.data().userImage,
});
});
});
});
return res.json(posts);
})
.catch((err) => {
res.status(500).json({ error: err.message });
});
};
followData returned:
[
{
"receiverHandle": "John Doe",
"senderHandle": "bear"
},
{
"senderHandle": "bear",
"receiverHandle": "Yikies"
},
{
"receiverHandle": "bear",
"senderHandle": "bear"
},
{
"receiverHandle": "anon",
"senderHandle": "bear"
},
{
"senderHandle": "bear",
"receiverHandle": "BigYikes"
}
]
There are multiple issues with this code.
You are not waiting promise to be resolved.
Multiple returns statements
You would not create global arrays like posts and followData[you can return in then for next callback]
Code:
// fetch home-specific posts (of users following)
exports.getHomePosts = (req, res) => {
const followDocument = db
.collection("follows")
.where("senderHandle", "==", req.params.handle);
followDocument
.get()
.then((data) => {
if (data.query.size == 0) {
throw new Error("NOT_FOUND");
} else {
return data.map((doc) => doc.data());
}
})
.then((followData) => {
const promises = followData.map((follow) => {
return db
.collection("posts")
.where("userHandle", "==", follow.receiverHandle)
.where("location", "==", "explore")
.get();
});
Promise.all(promises).then((results) => {
const posts = results
.map((data) => {
return data.map((doc) => ({
postId: doc.id,
body: doc.data().body,
userHandle: doc.data().userHandle,
createdAt: doc.data().createdAt,
commentCount: doc.data().commentCount,
likeCount: doc.data().likeCount,
userImage: doc.data().userImage,
}));
})
.flat();
return res.json(posts);
});
})
.catch((err) => {
if (err.message === "NOT_FOUND") {
return res.status(400).json({ error: "Not following any users" });
}
res.status(500).json({ error: err.message });
});
};

Inability to pull from a nested array

I have this query
router.delete('/:_id', async (req, res) => {
const {_id} = req.params;
const errors = [];
console.log(_id);
await Promise.all([
// Pon.findOneAndDelete({_id}).catch((e) => {
// console.log(e);
// errors.push('Something went wrong. Pon was not deleted');
// }),
// ^^^^^^^^^ this part worked. Wanted to just test the other query
User.findOneAndUpdate({_id: req.user._id}, {$pull: {pons: {_id}}}).catch((e) => {
console.log(1, e);
errors.push('Something went wrong. Pon reference was not deleted from user');
}),
]);
if (errors.length > 0) {
console.log(2, errors);
res.json({ok: false, errors});
} else {
res.json({ok: true});
}
});
I am just trying to remove an element from user object. Here's the object
{
"_id": {
"$oid": "5ea2d8cffe35b93e84f7962b"
},
"pons": [
{
"$oid": "5ea98b181a2be04ec87aa710" // this is what I want to remove
}
],
"email": "test#test.tes",
"password": "$2a$12$VJ0MkcGUs42pikT42qLpyOb0Sd53j9LXH8dY9RdR/GcmUVzJoP8gi",
"__v": 0
}
This query doesn't throw any errors, catch doesn't catch anything, so I don't know what I'm doing wrong. I tried just doing {pons: _id} instead of {pons: {_id}} but no luck.
The _id is correct. Checked with console.log.
What am I missing?
_id is just a String. If you want to match an ObjectId, you have to wrap it like this mongoose.Types.ObjectId(_id)
const ObjectId = mongoose.Types.ObjectId
User.findOneAndUpdate(
{ _id: ObjectId(req.user._id) },
{ $pull: { pons: ObjectId(_id) } }
)
Since you are querying by _id, you could also use User.findByIdAndUpdate() which will wrap req.user._id with ObjectId for you.
const ObjectId = mongoose.Types.ObjectId
User.findByIdAndUpdate(req.user._id, { $pull: { pons: ObjectId(_id) } })

Categories

Resources