meteor collection.update is not updating document - javascript

I am trying to trigger an update within a client method (thinking to move into server later) as follows:
Meteor.methods({
// Calling this and passing in a currentSelected value = "avatar" on click
'updateSelectedDocument' : function(currentSelected) {
var current = LayoutVariations.findOne({elementID: currentSelected});
var index = current.currentIndex;
myCollection.update({_id :current._id}, {currentIndex: 2});
}
});
The .update should find the document and update that document's currentIndex property, which is an integer.
I ran the myCollection.update({_id :current._id}, {currentIndex: 2}); in the console by passing in the _id (e.g. "GRvujvgBEmem3Dp3d") and it works. It's just not updating when I call it within a method and it's not throwing any errors.
Wondering what could be the issue.

Use the $set operator in your update to replace the value of the field currentIndex with the specified :
Meteor.methods({
// Calling this and passing in a currentSelected value = "avatar" on click
'updateSelectedDocument' : function(currentSelected) {
var current = LayoutVariations.findOne({elementID: currentSelected});
var index = current.currentIndex;
myCollection.update({_id :current._id}, {$set: { currentIndex: 2 } }, function(error, affectedDocs) {
if (error) {
throw new Meteor.Error(500, error.message);
} else {
return "Update Successful";
}
});
}
});

Related

Invalid-key request passed to a map to retrieve the value. Handle this exception

I have a map, and am trying to retrieve a value based on the key passed in the form of "id". However in some cases, the "id" that is passed is invalid i.e. it is not present in the Map, which in turn makes the application crash. Is throwing the Error causing this issue ? I tried experimenting with the try-catch but it still continued to malfunction i.e. the screen stops loading on detecting this error. Not sure if I wrote the try-catch correctly. how do I best handle this to stop the application from malfunctioning in such a case and continue loading the screen.
Failed approach:
this.hmItems = {}; //Map<Integer,Item>
Address.prototype.getItem = function (id) {
var item = this.hmItems[id];
if (!item)
throw new Error("'Illegal argument: id=" + id);
return item;
};
Another failed approach:
this.hmItems = {}; //Map<Integer,Item>
Address.prototype.getItem = function (id) {
try {
var item = this.hmItems[id];
if (!item) throw "illegal id!!!!!!!!!";
return item;
} catch(err) {
//log exception
}
}
Use hasOwnProperty to see if the property exists on the hmItems object:
this.hmItems = {}; //Map<Integer,Item>
Address.prototype.getItem = function(id) {
if (!this.hmItems.hasOwnProperty(id)) {
throw new Error("'Illegal argument: id=" + id);
}
return this.hmItems[id];
};
Just checking var item = this.hmItems[id]; if (!item) isn't a good test because it'll fail even if the property exists on the object but is falsey, like 0 or null.
Live demo:
class Address {
hmItems = {
1: 10,
2: 0
};
getItem(id) {
if (!this.hmItems.hasOwnProperty(id)) {
throw new Error("'Illegal argument: id=" + id);
}
return this.hmItems[id];
}
}
const a = new Address();
// Works:
console.log(a.getItem(1));
// Works:
console.log(a.getItem(2));
// Throws:
try {
console.log(a.getItem(3));
} catch(e) {
console.log(e.message);
}

'$set' is empty even though it's not

I have a problem in updating a document in MongoDB...
in the params.sendingMethodPushTime and SmsTime i receive a new Date();
tried setting the $ set inside the update function itself and tried to use hardcoded values
userScheme.statics.updateAlertSendingTimes = function (params, cb) {
var query = {uId: params.uIds};
var set = {};
if (params.alertType) {
set['alertSendingTimes'] = {};
set['alertSendingTimes'][params.alertType] = {};
set['alertSendingTimes'][params.alertType]['push'] = params.sendingMethodPushTime;
set['alertSendingTimes'][params.alertType]['sms'] = params.sendingMethodSmsTime;
var update = {
'$set': set
}
this.update(query, update, {upsert: true}, cb);
} else {
cb(null)
}
};
$set should pass and MongoDB document is updated but instead, I get $set is empty etc
EDIT: my mongoose version is 4.13.4 and my node version is 6.16 and params.alertType is a string received dynamically (in my case it's '​1' or '2')
The issue was with the scheme... it was alerts and not alert

unhandledpromiserejectionwarning in simple function in expressjs

This is my function:
/* function for add transaction */
function addtransaction(user_id,status,amount,date,description){
var saved = "";
function getLastId(){
Transactions.findOne({}, {}, { sort: { '_id' : -1 } }).lean().exec(function(err, lastTrans) {
if (err) {
return 1;
}else{
return parseInt(lastTrans.id) + 1;
}
});
}
var newId = getLastId();
var newTransactions = new Transactions({
id : newId,
user_id : user_id ,
status : status ,
amount : amount ,
date : date ,
description : description
});
if (newTransactions.save()){
return true;
}else{
return false;
}
}/* end function */
And this is my console error:
Can you help me to solve this error?
enter image description here
I updated my function but there is still error!
It seems like the error is here getLastId + 1 .getLastId is a function and 1 a number, and a function cannot be cast to a number. Most likely you forgot to put the parentheses to get the result out off the function call.
Try replace getLastId + 1 with getLastId() + 1
You may missed the () in:
id: getLastId + 1
Your issue is that you're not waiting for your getLastId() to actually return since it is async. Since it is async, while getLastId() is still working, your code has already moved on to creating a new Transaction where newId is undefined since nothing has been returned. So you need to place your code dependent on newId into the callback of your Transaction.findOne() or pass in a callback to getLastId().
Just to note, your addtransaction function should take a callback function as well so you can return the outcome of newTransactions.save() to the called in an asynchronous way. I did not do this in the below code examples since I do not know how your other code is structured.
I would also say that Approach #1 below is the preferable one since its less code, doesn't involve defining getLastId() everytime addtransaction() is called and it is has less callbacks than Approach #2.
Approach #1, place logic in Transactions.findOne()
function addtransaction(user_id, status, amount, date, description) {
Transactions.findOne({}, {}, { sort: { '_id' : -1 } }).lean().exec(function(err, lastTrans) {
var newId = err ? 1 : (parseInt(lastTrans.id) + 1);
var newTransactions = new Transactions({
id : newId,
user_id : user_id ,
status : status ,
amount : amount ,
date : date ,
description : description
});
return newTransactions.save();
});
}
Approach #2, Pass in Callback
/* function for add transaction */
function addtransaction(user_id,status,amount,date,description){
var saved = "";
function getLastId(callback){
Transactions.findOne({}, {}, { sort: { '_id' : -1 } }).lean().exec(function(err, lastTrans) {
if (err) {
return callback(null, 1);
} else {
return callback(null, parseInt(lastTrans.id) + 1);
}
});
}
getLastId((err, newId) => {
var newTransactions = new Transactions({
id : newId,
user_id : user_id ,
status : status ,
amount : amount ,
date : date ,
description : description
});
return newTransactions.save();
});
}/* end function */
Its also worth noting that assigning return data directly from a function that is async isn't the proper way to construct asynchronous functions in Node.js. See this answer for the proper way to construct these types of functions.

Parse Javascript API Cloud Code afterSave with access to beforeSave values

I'm using Parse Cloud Code to do before/afterSave processing. I'd check the beforeSave value of an attribute in the afterSave hook - for example, do something when parseObj.get('status') transitions from processing => complete. I can get access to the oldVal/newVal for changed attributes in the beforeSave handler, but I can't find a way to pass the oldVal to the afterSave handler without saving as a DB field.
I tried to pass the values as an attribute to the response and response.object objects, neither makes it through to the afterSave
Parse.Cloud.beforeSave('ParseObj', function(request, response) {
var checkDirty, isDirty, parseObj, prevQ;
// request keys=["object","installationId","user","master"]
if (request.object.isNew()) {
return response.success();
} else {
parseObj = request.object;
checkDirty = ['status']; // array of all attrs to check
isDirty = [];
_.each(checkDirty, function(attr) {
if (parseObj.dirty(attr)) {
isDirty.push(attr);
}
});
console.log("isDirty=" + JSON.stringify(isDirty));
if (isDirty.length) {
prevQ = new Parse.Query('ParseObj');
return prevQ.get(parseObj.id).then(function(prevParseObj) {
var newVal, oldVal;
console.log("prevParseObj, id=" + prevParseObj.id);
oldVal = _.pick(prevParseObj.toJSON(), isDirty);
_beforeSave(parseObj, oldVal); // do something here
request.previousValues = oldVal
request.object.previousValues = oldVal
return response.success();
}, function(err) {
return response.error("parsObj NOT FOUND, parseObj.id=" + parseObj.id);
});
} else {
return response.success();
}
}
});
Parse.Cloud.afterSave('ParseObj', function(request) {
var parseObj;
// request keys=["object","installationId","user","master"],
oldVal = request.previousValues // undefined
oldVal = request.object.previousValues // also, undefined
parseObj = request.object;
_afterSave(parseObj, oldVal) // do something else here
return;
});
Any ideas?
I looked into this some more, and I ended up saving to the Parse object temporarily and removing it like this:
//Add the value you need to the object prior to saving using an "oldValue" key
yourPFObject["oldValue"] = value (this is in your SDK somewhere where the save happens)
//Get that value in afterSave in Cloud Code
var old = object.get("oldValue")
//Do whatever you need to do with "old"...
//Remove the temporary old value so it doesn't stay in the database
object.unset("oldValue")
object.save()
I hope that helps. Good luck!

YDN-DB How to verify if a record exists?

I'm trying to verify if a specific record exist inside a table by a given ID. For example:
var id = 23;
db.count('products',id).done(function(count) {
if(count>0){
db.get('products',id).done(function(r) {
//Do something
});
}else{
alert('No product found');
}
});
When I try this, I get the following error: uncaught exception: null
I'd really appreciate your help Thanks!.
Your solution is almost correct.
In IndexedDB API, there is no exists method, probably because it can be emulated using count method. But count method accepts only key range, so existence test should be:
var id = 23;
db.count('products', ydn.db.KeyRange.only(id)).done(function(cnt) {
if (cnt) { // exist
} else { // no exist
}
});
Another reason, exists method don't exist in the IndexedDB api is that, get don't give error for non-existing key. So you can safely, and recommended, to do:
var id = 23;
db.get('products', id).done(function(product) {
if (product) { // exist
} else { // no exist
}
});
I would like to point out that, in these two ways to detect existence, the first method is more efficient because it avoid deserialization. So if you just need to test for existence, use first method. For retrieving a record, which may or may not exist, use second method.
EDIT:
To query a record by primary key, id, or unique secondary key, sku
/**
* #param {string} id id or sku
* #param {Function} cb callback to invoke resulting record value. If not exists in the
* database, null or undefined is returned.
*/
var getByIdOrSku = function(id, cb) {
var req = db.get('items', id);
req.done(function(item) {
if (item) {
cb(item)
} else {
db.values('items', 'SKU', ydn.db.KeyRange.only(id), 1).done(function(items) {
cb(items[0]); // may not have result
});
}
});
};
If you prefer promise way:
db.get('items', id).then(function(item) {
if (item) {
return item;
} else {
return db.values('items', 'SKU', ydn.db.KeyRange.only(id), 1).done(function(items) {
return items[0];
});
}
}).done(function(item) {
// result query as as id or SKU
console.log(item);
});

Categories

Resources