cut user id mongoose response - javascript

I'm trying to response from my backend a piece of user id by using lodash, i tryed with id.slice(2, 9) but i get a response without _id. What i'm doing wrong? thanks in advance.
getUserData: (req, res, next) =>{
User.findById(req.params.userId,
(err, user) => {
if (!user)
return res.status(404).json({ status: false, message: 'User record not found.' });
else
return res.status(200).json({ status: true, user: _.pick(user, ['_id'.slice(2, 9), 'domain', 'store', 'settings']) });
}
);
},

getUserData: (req, res, next) =>{
User.findById(req.params.userId,
(err, user) => {
if (!user)
return res.status(404).json({ status: false, message: 'User record not found.' });
else {
let json = { status: true, user: _.pick(user, ['_id', 'domain', 'store', 'settings']) };
json.user._id = json.user._id.slice(2, 9);
return res.status(200).json(json);
}
}
);
},
Pick the parts you want
Slice the _id to replace it with just the part you want
return the object

Edit:
To cut the ObjectId is necessary first to parse to string, so you need something like this:
var newUserId = user._id.toString().substring(3,user._id.toString().length)
But there is a problem (I think, not tested). If you try to store the cut id into a model object, maybe mongoose don't allow you to add an string (and no valid ObjectId) value instead of ObjectId.
Maybe is neccesary create another object instead of the model with the schema.
Old answer (unrelated) but maybe usefull for somebody:
If you want to hide the result just use select() into your query.
You run a query and then select which fields do you want to get or not into the response.
The proper way to code it is as follows:
query.select({ field1: 1, field2: 1 });
//or
query.select('-field1');
//and many other ways
Docs here

Related

Why doesn't findByIdAndUpdate update the document?

I have my problem with the following function
export function updateLine(req: Request, res: Response) {
if (!req.params.id || !req.body) return res.status(400).send({ message: 'Client has not sent params' });
Line.findByIdAndUpdate(req.params.id, req.body, async (err, lineUpdated) => {
console.log("req.params.id", req.params.id)
console.log("lineUpdated", lineUpdated)
console.log("req.body", req.body)
if (err) return res.status(409).send({ message: 'Internal error, probably error with params' });
if (!lineUpdated) return res.status(404).send({ message: 'Document not found' });
if (req.params.id !== lineUpdated.id) await Key.updateMany({ 'line': req.params.id }, { 'line': lineUpdated._id }).exec(err => {
if (err) return res.status(500).send({ message: 'Key Internal Server Error' });
});
return res.status(200).send({ data: lineUpdated });
});
}
What I'm trying to do is just update the document req.params.id with what contains req.body
The responses to the console.log () shown are as follows
req.params.id ACCSEH
lineUpdated {
_id: 'ACCSEH',
name: 'Accesorios (SEH)',
started: 2020-04-21T20:25:10.395Z,
__v: 0
}
req.body { id: 'ACCSEJ', name: 'Accesorios (SEH)' }
I am doing something wrong?
I already know that lineUpdated will return the function to me before the change. I mean when I do the query to see the change nothing has changed
enter image description here
Referring to the documentation:
The field name _id is reserved for use as a primary key; its value
must be unique in the collection, is immutable, and may be of any type
other than an array.
You can not change _id field once it is inserted into the collection
When finding and updating by ID you can't give it an ID in the object - you need to give it an object that has some combination of the other items (name, started, _v).

How to get data with just inserted data with Sequelize in PostgreSql?

I want to get updated table values after I add user to my "WOD" table. For instance, I have 2 users in my WOD table and after I add third user , I want to return a response to client with I have just inserted data (third guy). But now , I can only return first 2 users because I can not take updated values. Of course I can make another query to get updated table values after I insert, but is there any better solution ? Here is my codes;
const addUser = async (req, res) => {
try {
const { userId, wodId } = req.body;
if (!userId || !wodId) {
res.status(400).send({ status: false, message: 'need userId and wodId' });
}
const wod = await Wod.findByPk(wodId, {
include: [
{
model: User,
as: 'Participants',
through: { attributes: [] }
}
]
});
//check capacity if full.
if (wod.Participants.length >= wod.capacity) {
res
.status(403)
.send({ status: false, message: 'Capacity of this class is full!' });
}
const result = await wod.addParticipants(userId);
res.status(201).json({ status: !!result, wod });
} catch (error) {
res.status(500).send({ status: result, message: error.message });
console.log(error.message);
}
};
As a result of many-to-many association sequelize.sync will generate some functions for us. You are used addParticipants function and this returns an array that added to the assocation(userwod) table.
In this array you will find some id fields(join table fields) because you just run like this INSERT INTO 'user_wods' ('user_id''wod_id') VALUES (2,1). If you want to return the added user's information then you should run a SELECT * FROM 'user' WHERE 'id'=2.
You must call reload function for fetch the third guy.
await wod.reload()

Elegant way to update many properties with mongoose

I have a model with 7 properties and want to update them all when there is an edit request from front-end. Is there any elegant way to do so, or do I have to type all of them manually like in my code bellow (whitch by the way works fine for me, but looks really ugly).
exports.saveDish = (req, res, next) => {
const {
name,
description,
price,
category,
vegetarian,
hot,
menuPosition,
} = req.body;
Dish.findById(req.body._id)
.then(oldDish => {
if (oldDish) {
oldDish.name = name;
oldDish.description = description;
oldDish.price = price;
oldDish.category = category;
oldDish.vegetarian = vegetarian;
oldDish.hot = hot;
oldDish.menuPosition = menuPosition;
oldDish.save();
return res.status(204).json({ message: 'Dish data properly updated' });
}
const newDish = new Dish(req.body);
newDish.save();
return res.status(201).json({ message: 'New dish properly saved' });
})
.catch(err => console.log(err));
};
This will update an existing record and return the updated value. If no matching record is found, it will return a falsey value to the callback or promise (can't remember if it's null or something else).
Dish.findByIdAndUpdate(req.body._id, updates, {new: true}, cb)
You can try something like this :
exports.saveDish = (req, res, next) => {
/**
*
* upsert: true --> helps to insert new document if no matching doc exists
* new: true --> returns new document in output
* rawResult: true --> helps to find out whether update or insert operation is done
*
* Dish is a mongoose schema where findByIdAndUpdate is only from mongoose,
* which internally converts a string from it's first parameter into {_id : ObjectId('req.body._id')}, also uses $set operation on req.body
*
* Print data to check what's being returned, you might see entire document(data.value) being returned with some other information
*
* */
Dish.findByIdAndUpdate(req.body._id, req.body, { upsert: true, new: true, rawResult: true }, (err, data) => {
if (err) { console.log(err); res.status(200).json({ message: 'Operation Failed' }) }
if (data.lastErrorObject.updatedExisting) return res.status(204).json({ message: 'Dish data properly updated' });
return res.status(201).json({ message: 'New dish properly saved' });
})
};
Here you're updating existing document (adding new fields or updating the existing fields w.r.t. what's there is req.body) or inserting an entire new document if no matching _id is found in database, this way you avoid multiple DB calls. Here I've made it in callbacks, but earlier I've actually done it in async await, it does work either way, this should work for all of your cases listed above !!
Ref : Mongoose findByIdAndUpdate
#EddieDean, your way worked almost fine, it turns out that you have to pass any id to findByIdAndUpdate() method, so I edited it a little bit to work with unique, new dishes too.
Working code just in case:
exports.saveDish = (req, res, next) => {
if (req.body._id) {
Dish.findByIdAndUpdate(
{ _id: req.body._id },
{ ...req.body },
{ useFindAndModify: false }
)
.then(oldDish => {
if (oldDish) {
oldDish.save();
return res
.status(204)
.json({ message: 'Dish data properly updated' });
}
})
.catch(err => console.log(err));
} else {
const newDish = new Dish(req.body);
newDish
.save()
.then(result => {
return res.status(201).json({ message: 'New dish properly saved' });
})
.catch(err => console.log(err));
}
};

writing a query and return one value from a database in node js and mongoose

im writing a query in node js, my model of schema has 3 objects( userid, tokenid, mediaid), and i want to find the token id of a certain userid and use it in another function.
my code is as below:
app.get('/registeruser/:userid', function(req, res){
var name = req.params.userid;
user.findOne({userid: name},function(err, users1){
if(!users1){
res.send('Error 404, user not found');
return res.status(404).send();
}
else{
var query = user.find({tokenid: 1});
query.where({userid: name});
query.exec(function(err, result){
if(err){
res.send('erooooooor')
}
else{
res.send('okk')
console.log(result)}
});
user is the name of my model.
i run my code and i expect it to return the tokenid but it returns this: []
with these in my database:
userid: 'hgfj1234',
tokenid: 'juiodkdn12345678',
mediaid: ['med10', 'med11']
when i write userid: 'hgfj1234' it gives me this: [] but i want the real tokenid.
if anyone can help me i really appreciate it.
thanks in advance.
You don't need to do additional request to get record from mongodb.
That's enough to use findOne with complex attributes.
Try this:
app.get('/registeruser/:userid', function(req, res) {
var query = {
userid: req.params.userid,
tokenid: {$exists: true, $not: {$size: 0}}
};
user
.findOne(query)
.exec(function(err, User) {
if(err) { // error happen,
console.error(err); // log error
return res.status(500).send({
success: false,
message: 'System error'
}); // respond with 500 status and send json response with success false and message. return will stop execution to go down
}
if(!User) { // response from database was empty or null
return res.status(404).send({
success: false,
message: 'User not found'
}); // respond with 404 status and send json response with success false and message. return will stop execution to go down
}
res.send({
success: true,
tokenid: User.tokenid
}); // and at last everything is ok, we return json response with success and tokenid in response
});
});
attributes in query variable means to request mongodb to give us document with userid defined in request and that has tokenid that is defined and not is empty string (not size 0).
if You still did not getting desired result so check database for existence of necessary document.
If I understand your query right, you will reduce all find() calls to the tokenid with value 1. You will receive only any result, if the user has the token "1".
I suspect you wanted to code a projection, that is the second parameter on find():
var query = user.find({"userid": name});
query.select({"tokenid": 1})
.exec(function(err, result){
if(err){
res.send('erooooooor')
}
else{
res.send('okk')
console.log(result)}
});

Existing property return undefined

I started the implementation of a RESTful API usin node.js, express, and mongodb. Everything went well until now, I've a route to authenticate an user as follow:
apiRoutes.post('/authenticate', function(req, res) {
User.findOne({
nickname: req.body.nickname
}, function(err, user) {
if (err) throw err;
if (!user) {
res.json({
success: false,
message: 'Authentication failed. User not found.'
});
} else if (user) {
console.log(user);
console.log(user.nickname);
console.log(user.email);
console.log(user.password);
console.log(user.sexe);
if (user.password != req.body.password) {
res.json({
success: false,
message: 'Authentication failed. Wrong password.'
});
} else {
var token = jwt.sign(user, app.get('salt'), {
expiresInMinutes: 1440 // expires in 24 hours
});
res.json({
success: true,
token: token
});
}
}
});
});
The user is retrieved, and loged in the console as follow:
{ sexe: 'H',
email: 'MrPanda#gmail.com',
password: 'bambou',
nickname: 'MrPanda',
_id: 56cb703e7aef3f83c7dac0a7 }
which is perfect, but then, the three following consol.log return the three following lines:
MrPanda
MrPanda#gmail.com
undefined
H
I see absolutely no reason why the password is undefined at this point, I tried to change the attribute name to 'mdp', same issue... Any ideas ? Thanks
If you are using mongoose it does not return a plain JSON object. It is actually a special mongoose object and may not function how you expect.
You have two options:
Convert the mongoose object to a JSON object.
Add {lean: true} to the Users options parameter.
OR JSON.stringify(user)
OR user.toJSON()
Use the proper get() and set() methods (which you should be doing anyways).
user.get('password')
user.get('email')
user.get('name')
Try that and let me know if it doesn't work still.

Categories

Resources