Mongoose update subdocument with save is not working - javascript

Trying to update an object in an array.
My code:
module.exports = (req, res) => {
var givenProject = req.body;
var query = mongoose.model('cv').findOne({alias: req.params.alias});
query.exec(function(err, cv){
if(err){
res.status(400).send({message: 'Could not find cv with alias: ' + req.params.alias, err: err})
}
var doc = cv.projects.id(req.params.id);
doc.langTitles = givenProject.langTitles;
doc.langDescriptions = givenProject.langDescriptions;
doc.save(function(err){
if(err){
res.status(400).send({message: 'Could not update project', err: err});
return;
}
res.status(200).send();
});
});
};
No error is given. var doc is found and the posted data have the same data structure as doc and it differs from the original.
The doc is not updated. What am I missing here?

According to the Mongoose docs:
Sub-documents enjoy all the same features as normal documents. The
only difference is that they are not saved individually, they are
saved whenever their top-level parent document is saved.
Therefore try replacing
doc.save(function(err) ...
with
cv.save(function(err) ...

Related

PUT does not update Mysql thru REST api / JWT

I am trying to make an update request using Jwt (Tokens) and Node.Js with a backend in mysql.
It just tells me in Postman that the record has been updated, i try to see where the update took place and i could not find a thing. Nothing updated.
My code is looking thus :
app.put('/api/v1/logistics/update_profile', async function (req, res, next) {
try {
if (
!req.headers.authorization ||
!req.headers.authorization.startsWith('Bearer ') ||
!req.headers.authorization.split(' ')[1]
) {
return res.status(422).json({ message: 'Please Provide Token!' });
}
const theToken = req.headers.authorization.split(' ')[1];
const decoded = jwt.verify(theToken, 'fasta-logistics');
var fullname = req.body.fullname;
var email = req.body.email;
var state = req.body.state;
var city = req.body.city;
var phone_num = req.body.phone_num;
var company_type = req.body.company_type;
var company_name = req.body.company_name;
var company_regnum = req.body.company_regnum;
var l_licensenumber = req.body.l_licensenumber;
var company_address = req.body.company_address;
dbConn.query(
'UPDATE XXXXXx SET fullname =? , email =?, state=?, city=?, phone_num=?, company_type=?, company_name =?, company_regnum =?, l_licensenumber =?, company_address =? where id =?',
[
fullname,
email,
state,
city,
phone_num,
company_type,
company_name,
company_regnum,
l_licensenumber,
company_address,
decoded.id,
],
function (error, results, fields) {
if (error) throw error;
return res.send({
error: false,
data: results,
message: 'User Updated Successfully',
});
}
);
} catch (err) {
next(err);
}
});
Why does it tell me the records has been updated and nothing happens? Please I need guidance here of some sort.
return res.json({ error: false, data: results, message: 'User Updated Successfully' }); should work.
To be honest, I don't know how the "dbConn.query" works, but I guess you misspelled the arguments order or something like that. I can suggest you to use ORMs instead (at least query builders like knex), because they have declarative and more readable code, huge doc and community and issues like this doesn't exist in there.

Mongoose findOneAndUpdate doesn't find (or update) in Node

I'm trying to add user input (url's) to a database with Mongoose but also checking if the added data already exists. Instead it seems to be creating a new model every time.
This shows the res.json(input) on screen, not the test json
var mongo = require('mongodb');
var mongoose = require('mongoose');
var cors = require('cors');
// Basic Configuration
var port = process.env.PORT || 3000;
process.env.DB_URI="omg it's my secret url"
// Connect to DB.
mongoose.connect(process.env.DB_URI, { useNewUrlParser: true, useUnifiedTopology: true }).
catch(error => handleError(error));
mongoose.connection.on('error', err => {
console.log(err);
});
app.use(cors());
//First we create a schema and Model in MongoDB.
const urlSchema = new mongoose.Schema({
original_url: String,
short_url: Number
});
const urlModel = mongoose.model('urlModel', urlSchema);
app.post(/PATH, function(req, res, done) {
//Now we check if the input-url was actually valid.
if(!/(^https:\/\/)/.test(req.body.url)){
res.json({error: "Invalid url"});
}
//If it's valid we will start creating a model in the DB.
else {
var userUrl = req.body.url;
var urlNumber = 0;
var input = new urlModel({
original_url: userUrl
});
//Now we check if the url was already added to the database and return a new or updated item.
urlSchema.pre('save', function (next) {
var query = {'original_url': userUrl };
urlModel.findOneAndUpdate(query, userUrl, {upsert: true}, function(err, doc) {
if (err) return res.send(500, {error: err});
res.json({'test': 'test'});
});
});
res.json(input);
urlNumber++;
input.save(function(err, data) {
if (err) return console.log(err);
done(null, data);
});
};
});
As you can see I also have a problem updating the number that I want to attach to the url in the database, since I re-assign 0 to urlNumber at the beginning of the call. Must be because it's late but I can't seem to find a way to update that number correctly. I tried two variables and checking them against each other and an if(urlNumber > 0), but that's a problem I'm still solving. Seems so simple..
Anyway the question here is: why doesn't findOneAndUpdate seem to update? The returned res.json(input) shows a new '_id' every time, which tells me it does actually create new models every run.
Example returns
#1
{
_id: eksdjh3948wryeids293ren12;
original_url: "https://www.correct.com"
short_url: 0
}
#2
{
_id: eksdjh3948wryeids293ren13; // (<----- NEW NUMBER)
original_url: "https://www.correct.com"
short_url: 0
}
Your pre('save' function(next) {}) hook isn't calling next()
Turns out the .pre hook doesn't work with findOneAndUpdate! If I just remove that, the code now works as expected.

Append to array from mongodb query result and update database

I am developing an express webapp that has a friends list feature, the list is an array that is part of the user record in the database. What I am trying to do is to set up a route that adds the user from the route parameter to the logged in user's friends list array and updates the database.
My approach is to acquire the friends list document via collection.find() query (which works), modify it via javascript and update the database in a callback function.
The modifying part is what causes me problems, since the mongodb queries don't return json, but mongodb query objects. I don't know how to parse them. How can I get only the values to edit from that document?
router.get('/users/:specifiedUser/addfriend', function(req, res){
var currentUser = req.user.username;
var specifiedUser = req.params.specifiedUser;
var db = req.db;
var collection = db.get('usercollection');
var friendsList = [];
collection.find({ username : currentUser },{ friendsList : 1 }, function (err, result){
//TODO: convert result values to friendsList array, append specifiedUser to the array that is then updated in the callback
collection.update({username : currentUser },{friendsList : friendsList }, function (err) {
if (err) {
// return error if it fails
console.log(err.message);
return res.render('index', { error : err.message });
};
});
if (err) {
// return error if it fails
console.log(err.message);
return res.render('index', { error : err.message });
};
});
});

nodejs filter for mongodb data

I am using node and MongoDB for my project, here I need to set the filter on node script so that the data comes out from my MongoDB is filtered. But I do not understood how to use filter functionality on my script. It will be a filtered method, or I can use find method, or use loop
to filter the data in my MongoDB using node js script.
I am not exactly getting the idea.
What I want to do?
1) I had sent a set off a question from my MongoDB to the frontend.
2) Questions Data is coming from the front end and saved via using node js API. I have to save questionId, a score.
3) Next time when I have to send the data I NEED FILTER HERE so that data I have sent previously not sent again.
Id will generate automatically in MongoDB. So I have not mention id here.
This is my question schema
title: {type: String, required:true},
options: {type: Array, required:true},
result: {type: Array, required:true},
here i am storing my questionid, score values coming from frontend.
This is my question id, score save schema
child: {
quiz: {
questionId:{type:String},
score:{type:Number},
time:{type:String}
}
}
This is my node js API filter. I am trying this but I am not sure this is right or wrong. Please help me to fix this proble.m
this.childfilter = function(req, res, next) {
async.waterfall ([
function(callback) {
try {
var query = { 'child.quiz.score': 1 };
var projection = '';
childinfo.find(query,function(err,data) {
if(err) return next(err);
res.send(data);
callback(null, data)
});
}
catch(err) {
console.log(err);
return next(err);
}
},
function(callback, data) {
try {
var childq = new childquestion();
var query = { 'data.child.quiz.questionId' : childq._id };
var projection = 'id title options result';
childquestion.find(query,projection)
.skip()
.exec(function(err,data){
if (err) return next(err);
res.send(data);
});
}
catch(err) {
console.log('Error While Saving the result ' +err);
return next(err);
}
}
]);
}

NodeJS is asynchronous and my code doesn't run in the order I am expecting

postRegistrationHandler: function (account, req, res, next) {
console.log('postRegistrationHandler activated');
account.getCustomData(function(err, data) {
if (err) {
console.log(err.toString, "error string");
return next(err);
} else {
data.mongo_id = userCreationCtrl(account);
data.save();
next();
}
});
},
This function almost works properly, but the line:
data.save();
runs before the previous line finishes which means that the data I want to save isn't present at the appropriate time.
data.mongo_id = userCreationCtrl(account);
This line calls a function that creates a mongoDB document with information in the account object and then returns the _id (which is what I am trying to save.
I thought maybe using a .then() would help but that seems to be unavailable here for some reason. If anyone sees something I'm missing, that would be quite helpful. Thank you!
Here is the userCreationCtrl file as requested:
var UserSchema = require('./../models/UserModel.js');
var createNewUser = function (account, res, next){
// We will return mongoId after it is created by submitting a newUser
var mongoId = "";
// Save StormpathID (last 22 characters of account.href property)
var newStormpathId = account.href.slice(account.href.length - 22);
console.log('stormpath ID:', newStormpathId, 'just registered!');
console.log(account);
// Create new user from model by recycling info from the Stormpath registration form and include the stormpathId as well.
var newUser = new UserSchema({
stormpathId: newStormpathId,
firstName: account.givenName,
lastName: account.surname,
email: account.email,
street: account.street,
city: account.city,
zip: account.zip
});
// This saves the user we just created in MongoDB
newUser.save(function(err, result){
console.log(result);
if (err) {
console.error(err);
}
else {
console.log("User created in MongoDB, attempting to return mongoDB _id to stormpath customData");
// Keep track of the new user's mongo _id so we can return it to the previous function and save it as Stormpath custom data.
mongoId = result._id;
console.log(mongoId, "mongoid");
return result._id;
}
});
};
module.exports = createNewUser;
You have userCreationCtrl expecting 3 arguments, account, res, and next. next is the callback that should be called after the user is created so instead of return result._id you should call next like so:
// inside of createNewUser()
newUser.save(function(err, result){
console.log(result);
if (err) {
console.error(err);
}
else {
console.log("User created in MongoDB, attempting to return mongoDB _id to stormpath customData");
// Keep track of the new user's mongo _id so we can return it to the previous function and save it as Stormpath custom data.
mongoId = result._id;
console.log(mongoId, "mongoid");
// IMPORTANT change to make it all work...
// get rid of return result._id because its not doing anything
// pass the value to your callback function instead of returning the value
next(null, result._id);
}
});
then calling code in postRegistrationHandler should look like this:
account.getCustomData(function(err, data) {
if (err) {
console.log(err.toString, "error string");
return next(err);
} else {
// pass in a callback as the 3rd parameter that will be called by newUser.save() when its finished
userCreationCtrl(account, null, function(err, resultId) {
data.save();
next();
});
}
});

Categories

Resources