mongoose sort by date, multiple queries - javascript

I have a 'followed' section on my website and it retrives the posts of all users the user has followed. Is there a way of getting these sorted by date?
here's the code so far:
exports.followedPosts = async (req, res) => {
try {
const user = await User.findById(req.user._id);
const posts = [];
for (const follow of user.follows) {
const partPosts = await Post.find({ author: follow.user })
.select('-comments')
.populate('author')
.exec();
for (const post of partPosts) {
posts.push(post);
}
}
res.send(posts);
} catch (err) {
console.error(err.message);
res.status(500).send('server error');
}
};

You can find all posts of followed users in one query with $in and sort that query. Example:
let follow_users = user.follows.map(follow => follow.user);
const posts = await Post.find({ author: { $in: follow_users } })
.select('-comments')
.sort({date: 1})
.populate('author')
.exec();

Related

What is the problem in my code? How to delete a collection from MongoDB?

I am trying to delete a collection from mongodb using postmap API. Below is my code.The update function is working fine.But, delete function isn't working. It's displaying internal server error.I dont know why?
const router = require("express").Router();
const User = require("../models/User");
const bcrypt = require("bcrypt");
//uodate
router.put("/:id", async (req, res) => {
if ((req.body.userId === req.params.id) || req.body.isAdmin) {
if (req.body.password) {
try {
const salt = await bcrypt.genSalt(10);
req.body.password = await bcrypt.hash(req.body.password, salt);
}
catch (err) {
return res.status(500).json(err);
}
}
try {
const user = await User.findByIdAndUpdate(req.params.id, {
$set: req.body,
});
return res.status(200).json("Account has been updated");
}
catch (err) {
return res.status(500).json(err);
}
}
else return req.status(400).json("You can only update your account!!!");
});
//delete
router.delete("/:id", async (req, res) => {
if ((req.body.userId === req.params.id) || req.body.isAdmin) {
try {
await User.deleteOne(req.params.id);
return res.status(200).json("Account has been deleted");
}
catch (err) {
return res.status(500).json(err);
}
}
else return res.status(400).json("You can only update your account!!!");
});
module.exports = router;
Help me with thispostman API screenshot.
Try this:
await User.deleteOne({_id:req.params.id});
You are using deleteOne() method. If you want to delete whole collection, you should use deleteMany() method:
await User.deleteMany({});
The Model.deleteOne method expects a filter object, like {name: "value'"}. You are passing req.params.id which is a string. If you dig out the full text of the error, it will likely complain about that string not being an object.
You probably meant to use the Model.findByIdAndDelete method like
await User.findByIdAndDelete(req.params.id);

PERN stack: Iterating through array of data, my call to my database is not going through for every data record

I have been trying like crazy to find a solution to my problem, but nothing seems to work and I don't know where I am going wrong. I am creating an app using the PERN stack, and I have an array of data with a length of 24.
I iterate through my data array with following snippet of code (this is after trying to find solutions but the result is always the same):
const createEntry = async function (data) {
let whatever = await Promise.all(
data.map(async (item) => {
try {
console.log(`${item.name}`);
await Entry.post("/", item); //call to database
} catch (err) {
console.log(err);
}
})
);
whatever.then(console.log("I hate my life."));
};
I know the entire data array is being iterated through because of the console.logs, but the call to Entry.post() is only happening like maybe six times, and I am not getting all of my data entered into my database.
My express app.post code looks like this:
app.post("/url", async (req, res) => {
try {
const results = await db.query(
"INSERT INTO database (id, name) values ($1, $2)",
[
req.body.id,
req.body.name,
]
);
res.send({
status: "success",
results: results.rows.length,
data: {
entry: results.rows[0],
},
});
} catch (err) {
console.log(`${err.detail} for ${req.body.name}`);
}
});
So, I resolved this on my own and found a working solution.
My createEntry code from my question:
const createEntry = async function (data) {
let whatever = await Promise.all(
data.map(async (item) => {
try {
console.log(`${item.name}`);
await Entry.post("/", item); //call to database
} catch (err) {
console.log(err);
}
})
);
whatever.then(console.log("I hate my life."));
};
now looks like this:
const createEntry = async function (data) {
try {
let result = await CreateDB.post("/", data);
return result;
} catch (err) {
console.log(err);
}
};
And my app.post code
app.post("/url", async (req, res) => {
try {
const results = await db.query(
"INSERT INTO database (id, name) values ($1, $2)",
[
req.body.id,
req.body.name,
]
);
res.send({
status: "success",
results: results.rows.length,
data: {
entry: results.rows[0],
},
});
} catch (err) {
console.log(`${err.detail} for ${req.body.name}`);
}
});
Now looks like this:
app.post("/url", async (req, res) => {
try {
const results = await db.query(
"INSERT INTO database (id, name) values ($1, $2)",
[
req.body.id,
req.body.name,
]
);
res.send(res.rows[0]);
} catch (err) {
console.log(`${err.detail} for ${req.body.name}`);
}
});
And my call to my createEntry is:
let temp = {obj: some object};
createEntry(temp).then((newEntry) => {
dbArray.push(newEntry.data);
manipulateData(newEntry.data);
});
And with this I am now able to create a database entry, retrieve the database object and do work with it and it works for any size array which makes me really happy. So hopefully, if anyone has a similar problem, this can help.

MongoDB query doesn't find the requested entries

i'm trying to show a user specific data using req.session.user and pass the ID to the criteria i'm building. (every entry also has a user field so i can match) yet it does not work.
The Service :
async function query(filterBy) {
try {
const criteria = _buildCriteria(filterBy);
const collection = await dbService.getCollection('tab');
const tabs = await collection.find(criteria).toArray();
// const userTabs = await collection.find({ user: '62be030cb4de461a8462b863' }).toArray();
return tabs;
} catch (err) {
logger.error('Can not find tabs', err);
throw err;
}
}
The console.log('userId', userId) returns the Id I get from my controller
function _buildCriteria(filterBy) {
const criteria = {};
const { text, genre, userId } = filterBy;
console.log('userId', userId);
if (text) {
const txtCriteria = { $regex: text, $options: 'i' };
criteria.name = txtCriteria;
}
if (genre) {
criteria.genre = { $eq: genre };
}
if (userId) {
criteria.user = { $eq: userId };
}
return criteria;
}
The controller :
async function getTabs(req, res) {
try {
const userId = req?.session?.user?._id;
const filterBy = req.query;
const fitlerUpdated = { ...filterBy, id: userId };
const tabs = await tabService.query(fitlerUpdated);
res.json(tabs);
} catch (err) {
logger.error('Failed to get tabs', err);
res.status(500).send({ err: 'Failer ti get tabs' });
}
}
I tried using
const userTabs = await collection.find({ user: '62be030cb4de461a8462b863' }).toArray()
and it works yet it doens't work along with the criteria.
thanks for any help!
I have realize I accidentally passed the wrong key.
should have been id and not userId

mutiple get methods on the same route conflict in express and sequelize

I'm built simple product crud, so I have a route to search product by id and other to search product by name, when I make a requisition to http://localhost:4000/products?name=pen the routes are in conflict and don't return the product by name.
router.get('/products/:id', ProductController.getProductById);
router.get('/products/:name', ProductController.getProductByName);
and yours respect functions
const getProductById = async (req, res) =>{
try{
const { id } = req.params;
const product = await Product.findByPk(id);
if(product){
return res.status(200).json({ product });
}
return res.status(404).send('Product With ID does exist');
}catch (err){
return res.status(500).send({ error : 'Error on select by id'})
}
}
const getProductByName = async (req, res) =>{
try{
const name = req.query.name;
const product = await Product.findAll({
where: { name: name}
});
if(product){
return res.status(200).json({ product });
}
return res.status(404).send('Product With Name does exist');
}catch (err){
return res.status(500).send({ error : 'Error on select by id'})
}
}
If you use query parameters you should not indicate them in route path:
router.get('/products', ProductController.getProductByName);

How adding a field from a pulled mongodb document

I am trying to use an api to get the current value of a stock and multiply by the users stock.
When I make a call the route I get empty data, and when I print the value of the callback I get an empty array
function user_cur_portfolio(port, callback) {
let portfolio = [];
port.forEach( (stock) => {
var ticker = stock.name.toLowerCase();
alpha.data.quote(`${ticker}`).then(data => {
var fixed = Number((data['Global Quote']['05. price'] * stock.shares).toFixed(2));
let curr = {
name : ticker,
shares: stock.shares,
value : fixed
}
portfolio.push(curr)
});
})
callback(portfolio)
}
router.get('/portfolio', (req, res, next) => {
if (req.session.userId !== undefined){
User.findOne({ _id : req.session.userId }).exec(function (err, user) {
if (err)
next(err);
user_cur_portfolio(user.portfolio, (port)=>{
console.log(port);
res.render('portfolio', { portfolio: port, balance: user.balance});
});
})
} else {
res.redirect('/users/login');
}
});
When I make a call the route I get empty data Because alpha.data.quote is an async function and forEach is a sync function therefore, you will not be getting data in port variable.
So the best work around to this, is to use async await with all the synchronous function to behave them like async
async function user_cur_portfolio(port) {
let portfolio = [];
await Promise.all(
port.map(async stock => {
var ticker = stock.name.toLowerCase();
const data = await alpha.data.quote(`${ticker}`);
var fixed = Number((data['Global Quote']['05. price'] * stock.shares).toFixed(2));
let curr = {
name: ticker,
shares: stock.shares,
value: fixed
};
portfolio.push(curr);
})
);
return portfolio;
}
router.get('/portfolio', (req, res, next) => {
if (req.session.userId !== undefined) {
User.findOne({ _id: req.session.userId }).exec(async function(err, user) {
if (err) next(err);
const port = await user_cur_portfolio(user.portfolio);
console.log(port);
res.render('portfolio', { portfolio: port, balance: user.balance });
});
} else {
res.redirect('/users/login');
}
});

Categories