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

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

Related

Update an Object in indexed db by ignoring a value

I have written the below code
updatePublication(projectName, publicationId, publicationObj, callback) {
let self = this;
this.initDatabase(function (db) {
let tx = self.db.transaction(self.PUBLICATIONS, self.READ_WRITE);
let store = tx.objectStore(self.PUBLICATIONS);
let index = store.index(self.PROJECT_NAME);
let request3 = index.openCursor(IDBKeyRange.only(projectName));
console.log("hrere");
request3.onsuccess = function () {
let cursor = request3.result;
if (cursor) {
let updateObject = cursor.value;
if (updateObject.publicationID == publicationId) {
updateObject.publicationObject = publicationObj;
cursor.update(updateObject);
callback(publicationId);
}
cursor.continue();
} else {
callback(publicationId);
}
};
});
}
But this give error:
I checked the cause of error. It is beacuse , publicationObj which is passed has an object named _requestObjectBuilder which is of the type Subscriber.
used somewhere in the code like this:
_requestObjectBuilder = interval(1000).pipe(tap(() => {}));
Is there any way i can modify my updatePublication code to ignore this value?
Does indexed db support a query for ignoring a value and saving the data?
Note: If i set publicationObj._requestObjectBuilder = undefined, the data gets saved to indexedDB. But this breaks the functionality where _requestObjectBuilder is used.
Fixed the issue by cloning the object and setting it to undefined
let clonedObject = Object.assign({}, publicationObject);
clonedObject._requestObjectBuilder = undefined;
Now i am updating the clonedObject

Return list of Objects with Node js

I recently started development of a Node js application and it uses Selenium in a controller to fetch list of items from a web page and I want to return the fetched list of items as a JSON response.
exports.read_all_products = function (req, res) {
var driver = new webdriver.Builder().forBrowser('phantomjs').build();
driver.get('https://www.test.com/products?PC=' +req.params.category);
driver.wait(until.elementLocated(By.className('product-slide-all')), 20000, 'Could not locate the element within the time specified');
driver.findElements(By.className("product-slide-all")).then(function (elements) {
var arr = [];
elements.forEach(function (element) {
element.getAttribute("innerHTML").then(function (html) {
const dom = new JSDOM(html);
var obj = new Object();
obj.product_name = dom.window.document.querySelector(".product-name").textContent;
obj.product_code = dom.window.document.querySelector(".product-code").textContent;
obj.price = dom.window.document.querySelector(".product-price").textContent;
arr.push(obj);
});
});
res.json(arr);
});
}
Issue is I am always getting an empty JSON response even though items were added to the array. I want to know the proper way of handling this scenario.
Thanks.
It looks like the issue is because Selenium is running an async process, thus the response immediately returns because there is nothing blocking it.
findElements returns a Promise which you need to return the response from.
Take a look at How do I return the response from an asynchronous call?
Finally I was able to get it work with the help of webdriver.promise.map.
Moved web driver HTML extraction to separate function.
var findItems = function (category) {
var driver = new webdriver.Builder().forBrowser('phantomjs').build();
var map = webdriver.promise.map;
driver.get('https://www.test.com?PC=' + category);
driver.wait(until.elementLocated(By.className('product-slide-all')), 30000, 'Could not locate the element within the time specified');
var elems = driver.findElements(By.className("product-slide-all"));
return map(elems, elem => elem.getAttribute("innerHTML")).then(titles => {
return titles;
});
}
then call it from response handling function like bellow,
exports.read_all_products = function (req, res) {
findItems(req.params.category).then(function (html) {
var value;
var arr = [];
Object.keys(html).forEach(function (key) {
value = html[key];
const dom = new JSDOM(value);
var obj = new Object();
obj.product_name = dom.window.document.querySelector(".product-name").textContent;
obj.product_code = dom.window.document.querySelector(".product-code").textContent;
obj.price = dom.window.document.querySelector(".product-price").textContent;
arr.push(obj);
});
res.json(arr);
})
};
it's described in this stack overflow answers.

How to clone document to another collection? [duplicate]

My approach would be to get the document instance, and create a new one from the instance fields. I am sure there is a better way to do it.
You need to reset d1.isNew = true; as in:
Model.findById(yourid).exec(
function(err, doc) {
doc._id = mongoose.Types.ObjectId();
doc.isNew = true; //<--------------------IMPORTANT
doc.save(callback);
}
);
Can you clarify what you mean by "copy/clone"? Are you going trying to create a duplicate document in the database? Or are you just trying to have two vars in your program that have duplicate data?
If you just do:
Model.findById(yourid).exec(
function(err, doc) {
var x = doc;
Model.findById(yourid).exec(
function(err, doc2) {
var y = doc2;
// right now, x.name and y.name are the same
x.name = "name_x";
y.name = "name_y";
console.log(x.name); // prints "name_x"
console.log(y.name); // prints "name_y"
});
});
In this case, x and y will be two "copies" of the same document within your program.
Alternatively, if you wanted to insert a new copy of the doc into the database (though with a different _id I assume), that would look like this:
Model.findById(yourid).exec(
function(err, doc) {
var d1 = doc;
d1._id = /* set a new _id here */;
d1.isNew = true;
d1.save(callback);
}
);
Or if you're doing this from the outset, aka you created some document d1, you can just call save twice without setting the _id:
var d1 = new Model({ name: "John Doe", age: 54 });
d1.save(callback);
d1.save(callback);
There will now be two documents with differing _id's and all other fields identical in your database.
Does this clarify things a bit?
My two cents:
const doc = await DocModel.findById(id);
let obj = doc.toObject();
delete obj._id;
const docClone = new DocModel(obj);
await docClone.save();
So, a lot of these answers will work well for simple docs, but there could be an error case when you're trying to make a deep clone of complex documents.
If you have arrays of subdocs, for example, you can end up with duplicate _ids in your copied document, which can cause subtle bugs later.
To do a deep clone of a mongoose doc, I suggest trying something like:
//recursively remove _id fields
function cleanId(obj) {
if (Array.isArray(obj))
obj.forEach(cleanId);
else {
delete obj['_id'];
for (let key in obj)
if (typeof obj[key] == 'object')
cleanId(obj[key]);
}
}
let some_doc = await SomeModel.findOne({_id: some_id});
let new_doc_object = cleanId(some_doc.toObject());
let new_doc = new SomeModel(new_doc_object);
await new_doc.save();
This is going to be a pretty safe approach, and will ensure that every part of your object is cloned properly with newly generated _id fields on save.
The following code to clone documents:
Model.findById(yourid).exec(
function(err, doc) {
var newdoc = new Model(doc);
newdoc._id = mongoose.Types.ObjectId();
newdoc.save(callback);
}
);
For simply clone use this :
Context.findOne({
_id: context._id
})
.then(function(c) {
c._id = undefined;
c.name = context.name;
c.address = context.address;
c.created = Date.now();
return Context.create(c.toObject());
}).then(function(c) {
return res.json({
success: true,
context: context
});
}).catch(function(err) {
next(err, req, res);
});
const cloneDoc = (doc, model)=>{
const copyDoc = new Model({
...doc.toObject(),
_id: undefined,
});
copyDoc.isNew = true;
return copyDoc;
}
To copy a document into the same collection or different collection first get (query) the data and make a copy of the data. Afterwards remove the _id from the new list as you can't from the current data. This will allow you to insert a new record with new _id assigned from mongodb
change searchBy to what you are trying to find the document by.
change collectionA and collectionB to the name of the collection to create you copy to. Currently we are searching in collectionA and copying the data in collectionB
collectionA.find(searchBy).exec(function (err, doc) {
// create a new copy
let newDoc = { ...doc[0] }._doc;
// delete property from new copy (remove _id).
delete newDoc._id;
// insert copy into db
var newdoc = new collectionB(newDoc);
newdoc.save();
});
You can basically use .clone() to get a copy.
const cars = Cars.find();
const carsCopy = cars.clone();
await cars;
await carsCopy;
https://mongoosejs.com/docs/api.html#schema_Schema-clone

Passing parameters to the array updater method {$set: {"parameters": data}}

Comanda.findOneAndUpdate(id,{$set: {"orden.0.fondos.2.estadoitem": estado}}, {}, function(err, comanda)
I need to indirectly change that "2" in
$set: {"orden.0.fondos.2.estadoitem"
no matter what I do, i cant.. this will save my live =/..
i have tried everything, calling a var pos = 2; and then $set: {"orden.0.fondos.pos.estadoitem" also as a string pos= "2"; and nothing seems to work
thanks in advace
You can create $set field dynamically :
var set = { "$set": {} };
set.$set["orden.0.fondos." + pos + ".estadoitem"] = estado;
Comanda.findOneAndUpdate(id, set, {}, function(err, comanda) {
})
Seems orden is an array and so is fondos.
You could try
var doc = findOne({_id: id});
doc.orden[0].fondos[2] = 'anything you want';
doc.save((err,result)=>{})

meteor collection.update is not updating document

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";
}
});
}
});

Categories

Resources