mongoose pre hook findOneAndUpdate modify some field getting from another collection - javascript

I'm trying to modify a document in findOneAndUpdate pre hook, code given below
userSchema.pre('findOneAndUpdate', function (next) {
// this._update.$set
//var user = new User(this._update.$set)
var promiseArray = []
promiseArray.push(// Fetching some data from other collection)
Promise.all(promiseArray).then(function (values) {
if (values[0].length === 0) {
return next('Data not found')
} else {
this._update.$set.salary = values.salary
return next()
}
}).catch(function (err) {
next(err)
})
})
I'm getting error
TypeError: Cannot read property '$set' of undefined
I know why i'm getting this error because i'm accessing "this" keyword inside promise, "this" inside promise is different than "this" after pre method
How to solve this problem, I have tried to solve this problem by assigning
this._update.$set to different value shown example in commented code but after saving it's not modifying document we need to only change this._update.$set.salaray value. Any help appreciated

You can use .bind()
Promise.all(promiseArray).then(function (values) {
if (values[0].length === 0) {
return next('Data not found')
} else {
this._update.$set.salary = values.salary
return next()
}
}.bind(this)).catch(function (err) {
next(err)
})
})

Related

TypeError: Cannot read property 'hasOwnProperty' of undefined

I am making a node app that uses the npm library MojangJS to get the uuid of a Minecraft account from the account username. However, whenever this code segment is run, I get this error: MojangJS Error: TypeError: Cannot read property 'hasOwnProperty' of undefined.
let id;
await mojangjs.getUUID(usernameParts[1]).then(uuid => {
id = uuid;
}).catch(err => console.error(err));
You are using both await and .then at the same time. As Andrew you should stick to one way of doing it.
We dont know what 'usernameParts[1]' value is, but we can assume it is undefined from your comments.
I also assume you are in an async scope since you are already using the await keyword.
What i would do would be :
async function retrieveUUIDFromUsername ( username ) {
if (!username) return;
try {
return await mojangjs.getUUID(username);
} catch (err) {
console.log(err);
return;
}
}
and to call this function :
let id = await retrieveUUIDFromUsername(usernameParts[1]);
if (!!id) {
...
}
Note that the answer can be empty so keep that in mind while using the return value of it.

How to satisfy the "consistent-return" rule in eslint using an if-error-return pattern?

I have some code:
foo((error, data) => {
if (error) {
return;
}
// do something with data
});
This will cause a "consistent-return" error to be returned. I understand that this is an opinionated matter, however, what would be a reasonable way to satiate this rule?
Is my approach even correct? Should I be using return to effectively "break" within the callback body? Would I have to add an empty return statement after the // do something with data lines had been executed?
Consistent-return indicates that your function should always return the same type of data. So if you're returning undefined in a error case, you also should return undefined in the other cases.
foo((error, data) => {
if (error) {
return;
}
return;
});
If your function is supposed to return data when error is false, maybe your don't want to return undefined, and throw an Error instead.
foo((error, data) => {
if (error) {
throw new Error()
}
return data; // or anything else
});

meteor return empty cursor from publication

I have some middleware in front of my publications:
Meteor.publish(publicationIdentifier, function (...args) {
try {
middleware()
} catch(error) {
return Users.find('emptyCursor')
}
return Model.pubsub(...args)
})
I need to return an empty Cursor when the middleware throws an error.
I currently do that by using find with an invalid id on some arbitrary collection: return Users.find('emptyCursor')
Is there some better way to do this?
I have tried
return
return false
return null
return new Mongo.Cursor()
Like in the doc
// Sometimes publish a query, sometimes publish nothing.
Meteor.publish('secretData', function () {
if (this.userId === 'superuser') {
return SecretData.find();
} else {
// Declare that no data is being published. If you leave this line out,
// Meteor will never consider the subscription ready because it thinks
// you're using the `added/changed/removed` interface where you have to
// explicitly call `this.ready`.
return [];
}
});

Simple Check Function with node.js, pg-promise

I am trying to write a simple check() function following this example. The function successfully prints out "True!" but the return value of the function is undefined when I do console.log(submitModels.verifyOrganizationString(formInputs.organizationString));. How can I get the function to return true and false?
Right now the function only returns "Invalid organization string" even when the string is valid.
I am thinking this result has to do with the pg-promise library, but am not sure.
In the file submit.js, I have:
function verifyOrganizationString(organizationString) {
db.one("select * from organizations where organization_string=$1", [organizationString])
.then(data => {
console.log("True!");
return true;
})
.catch(error => {
console.log("False!");
return false;
});
}
module.exports = {
verifyOrganizationString,
};
In another file, I have
const submitModels = require('../models/submit.js');
function proccessSubmission(req, res) {
var formInputs = req.body;
console.log(submitModels.verifyOrganizationString(formInputs.organizationString));
if (submitModels.verifyOrganizationString(formInputs.organizationString)) {
submitModels.insertIntoDatabase(formInputs);
res.redirect('/');
} else {
res.send("Invalid organization string");
}
}
Your problem is due to both invalid use of promises and bad use of pg-promise.
If you want the function to return true/false depending on whether a record is found, change the function to this:
function verifyOrganizationString(organizationString) {
return db.oneOrNone("select * from organizations where organization_string = $1",
organizationString, a => !!a);
}
Then you can use it as one would a regular promise:
verifyOrganizationString('bla-bla')
.then(data => {
// data = true/false
})
.catch(error => {
// error
});
See also: SELECT ⇒ INSERT examples.
The reason you're getting undefined is because 'verifyOrganizationString' doesn't actually return anything. You need to return the promise created by your db.one chain.
Although the method will still not return true or false in that case but the Boolean wrapped in another promise so that you can chain the result of your verify function the same way you did with the result of db.one.

(JavaScript API 1.3 for Office) Custom Properties GetItemOrNull

I've created this a couple days ago in which i needed help regarding how to add custom properties to a said document.
First of all, I'm running Word 1701(7766.2047).
Let's say I have a method In which I return a said custom property. First I'd check if the custom property has been created already. I would do this with a simple getItemOrNullObject(key) and..
If returns null Then simply create it AND return it
Else return it
It is of my understanding that I need to do a return context.sync().then for the object get actually loaded with data? Am I doing too much return context.sync() calls for nothing?
Word.run(function(context) {
var customDocProps = context.document.properties.customProperties;
context.load(customDocProps);
return context.sync()
.then(function() {
var temp = customDocProps.getItemOrNullObject("X");
return context.sync()
.then(function() {
if (!temp) {
context.document.properties.customProperties.add("X", 1234);
temp = customDocProps.getItemOrNullObject("X");
return context.sync()
.then(function() {
return temp;
});
} else {
return temp;
}
});
});
});
The following code throws me an 'ReferenceError: 'Word' is undefined' at start but if I debug it it runs before it breaks
var customDocProps = context.document.properties.customProperties;
context.load(customDocProps);
return context.sync().{....}
Also have one more question. Say I want to update my custom property, would :
Word.run(function (context) {
context.document.properties.customProperties.add("X", 56789);
return context.sync();
});
override the old value with the new one?
If you read this far thank you! Any help is appreciated.
Cheers!
Thanks for asking this question.
Your code is correct except for one minor detail: All the *getItemOrNullObject methods do NOT return a JavaScript null, so your "if (!temp)" statement will not work as you expect. If you want to validate existence you need to call if(temp.isNullObject) instead.
Also a couple of suggestions:
customProperties.add() semantics is that if the property does exist, it will be replaced. So, If you want to create or change the property you don't need to check if it exists or not. If you want to read its current value you do. This answers your 2nd question.
I have a simplified and more efficient proposal for your code, if you are interested on loading a single property.
Word.run(function (context) {
var myProperty = context.document.properties.customProperties.getItemOrNullObject("X");
context.load(myProperty);
return context.sync()
.then(function () {
if (myProperty.isNullObject) {
//this means the Custom Property does not exist....
context.document.properties.customProperties.add("X", 1234);
console.log("Property Created");
return context.sync();
}
else
console.log("The property already exists, value:" + myProperty.value);
})
})
.catch(function (e) {
console.log(e.message);
})
We will update the documentation as this seems to be confusing.
Thanks!
I use these function to get or set custom properties
// sets a custom property on the current Word file
function setDocProperty (propName, propValue, callback) {
Word.run(context => {
context.document.properties.customProperties.add(propName, propValue)
return context.sync()
.then(() => {
callback(null)
})
.catch(e => {
callback(new Error(e))
})
})
}
// gets a custom property from the current Word file
function getDocProperty (propName, callback) {
Word.run(context => {
var customDocProps = context.document.properties.customProperties
// first, load custom properties object
context.load(customDocProps)
return context.sync()
.then(function () {
// now load actual property
var filenameProp = customDocProps.getItemOrNullObject(propName)
context.load(filenameProp)
return context.sync()
.then(() => {
callback(null, filenameProp.value)
})
.catch(err => {
callback(new Error(err))
})
})
.catch(err => {
callback(new Error(err))
})
})
}
You use them like this:
setDocProperty('docId', 28, () => {
console.log('property set')
})
getDocProperty('docId', (err, value) => {
if (err) {
console.log('Error getting property', err)
} else {
console.log('the property is ' + value)
}
})

Categories