Modifying mongoose object literal result does not work [duplicate] - javascript

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Why can’t you modify the data returned by a Mongoose Query (ex: findById)
First I am making the query to mongoDB, get all the correct results but only the small modification to object literal does not work. What I am trying to do, is adding new field to comments. I tried to use the DBref method but it didn't work so i make 2 queries now.
var query = Rss.findOne({ _id: itemId});
query.exec(function(err, feed) {
if (!err && feed.comments) {
console.log(feed.comments.length);
for (var index in feed.comments) {
var author = feed.comments[index].author;
if (author !== undefined) {
User.findById(author, function(err, user) {
/**Problem is here **/
feed.comments[index].name = 'Some random field';
console.log('Added new field' + util.inspect(feed));
});
}
}
}
});
Also the response is this without the missing .name field.
Added new field{ _id: 4f34f343c7b0434217000012,
original_link: 'http://com',
publish_date: Fri, 10 Feb 2012 10:36:00 GMT,
summary: 'some text',
title: 'title exampel',
comments:
[ { body: 'well',
author: 4f30265e6f60dc061d000002,
_id: 4f34f3b6f96c58541700000f,
create_date: Fri, 10 Feb 2012 10:38:46 GMT } ],
create_date: Fri, 10 Feb 2012 10:36:51 GMT }
// EDIT more information
Well i haven't found the answer but some how the console.log(feed.comments[index]) returns reference to function. Maybe someone who has more experience with mongoosejs could explain what would be workaround in this situation.
{ [Function] author: 'Some random field' }

You have to tell Mongoose to convert the result into a proper object. Before modifying the feed object simply call:
feed = feed.toObject();
And then you can add all the additional properties you want to it.

Related

How to perform date comparisons against postgres with sequelize

I want to delete all records with dates before 20 minutes ago. Postgres (or Sequelize) is not satisfied with the bare javascript Date object I provide as the comparison value.
I'm using sequelize 4.37 on top of a postgres 9.6 database.
The column in question was declared with type: Sequelize.DATE, which research suggests is equivalent to TIMESTAMP WITH TIME ZONE: a full date and time with microsecond precision and a timezone signifier. (That is also what I see when I use the psql CLI tool to describe the table.)
So, I do this:
const Sequelize = require('sequelize')
const { SomeModel } = require('../models.js')
// calculate 20 minutes ago
async function deleteStuff() {
const deletionCutoff = new Date()
deletionCutoff.setMinutes( deletionCutoff.getMinutes() - 20 )
await SomeModel.destroy({
where: {
[ Sequelize.Op.lt ]: { dateColumn: deletionCutoff }
}
})
But I get this error:
Error: Invalid value { dateColumn: 2018-11-21T21:26:16.849Z }
The docs suggest I should be able to provide either a bare javascript Date, or an ISO8601 string, but both throw the same Invalid Value error. The only difference is that, if I pass a string, the error shows single quotes around the value:
// error when dateColumn: deletionCutoff.toISOString()
Error: Invalid value { dateColumn: '2018-11-21T21:26:16.849Z' }
Well, this is pretty embarrassing. I structured the where clause incorrectly.
// BAD CODE
await SomeModel.destroy({
where: {
[ Sequelize.Op.lt ]: {
dateColumn: deletionCutoff
}
}
})
// GOOD CODE
await SomeModel.destroy({
where: {
dateColumn: {
[ Sequelize.Op.lt ]: deletionCutoff
}
}
})
Maybe I should delete the question. Maybe not -- the error I got probably could be more helpful.

Inserting account creation date from MongoDB into Handlebars?

I'm currently using MongoDB, NodeJS, and Handlebars and trying to convert user .id into a timestamp, then putting that timestamp into my HTML.
Right now, I can show the user.id on my website by writing {{ user.id }}, and I have a function that changes the id into a date:
var dateFromObjectId = function (objectId) {
return new Date(parseInt(objectId.substring(0, 8), 16) * 1000);
};
However, I'm having trouble piecing these two bits of information together to show the date on the website.
Any help would be appreciated; thanks!
You need to create handlebars helper:
Handlebars.registerHelper('toDate', function(objectId, options) {
return new Date(parseInt(objectId.toString().substring(0, 8), 16) * 1000);
});
and pass object id as an argument to it:
<p><b>Created at:</b> {{#toDate '58a4dd700000000000000000'}}{{/toDate}}</p>
So what you will see will be: Created at: Thu Feb 16 2017 00:00:00 GMT+0100
Assuming you are passing user MongoDB document from server in this form:
{
user: {
_id: ObjectId("58a62ef00000000000000000"),
first_name: "John",
last_name: "Doe"
}
}
You could use it like this:
<ul>
<li>First name: {{user.first_name}}</li>
<li>Last name: {{user.first_name}}</li>
<li>Created at: {{#toDate user._id}}{{/toDate}}</li>
</ul>
Try it out here.

function returning undefined instead of bool [duplicate]

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 5 years ago.
Probably missing something simple here but cant for the life of me figure out why the below function is returning undefined.
var isOrphanEan = function isOrphanEan (ean) {
Products.findOne({
'ean': ean
}, function (err, product) {
return product.orphan;
});
}
isOrphanEan(12345); //returns undefined
example of product
{
_id: 55ad6b442afbebe82d077a04,
orphan: true
}
edit:
console.logging product returns:
{ _id: 55ad6b442afbebe82d077a04,
ean: 4006643097328,
aw_product_id: 3295182687,
product_name: 'Multipower Shaker Neutral',
product_brand: 'Multipower UK',
product_description: '',
img_sml: 'http://images.productserve.com/noimage.gif',
img_lrg: '',
rating: '',
merchant_id: 2926,
price_current: 'GBP4.99',
price_rrp: '',
aff_link: 'http://www.awin1.com/pclick.php?p=3295182687&a=234945&m=2926',
direct_link: 'http://www.multipower.com/uk/product/multipower-shaker-09732/neutral',
merchant_product_id: '09732',
aw_image_url: '',
orphan: true,
created_at: Mon Jul 20 2015 22:42:28 GMT+0100 (BST),
updated_at: Thu Oct 08 2015 23:20:35 GMT+0100 (BST),
__v: 0 }
Use callbacks approach to cope with async responses:
var isOrphanEan = function isOrphanEan (ean, cb) {
Products.findOne({
'ean': ean
}, cb);
}
isOrphanEan(12345, function(err, product) {
console.log(product.orphan);
});
You are using a callback. Function isOrphanEan() does not return anything, rather findOne() will call the callback when the data becomes available. You need to process you product.orphan in the unnamed callback.

Mongoose find() returns undefined property and strange object

I have a bug that i can't resolve because for the first time it happen to me.
here is my query :
Pack.find(
{idclient: clientId }
)
.populate({
path: 'cards',
options: { sort: { 'position': 1 } }
})
. exec(function(err,pack){
if(err){
console.log(err);
}else{
///
// here are my logs
callback(pack);
}
});
When i try console.log(pack), i can see a strange return with \n
{ __v: 1,\n _id: 5596a859240cbd3832123b27,\n grouped: 0,\n idclient: \'4Z8OrisV2AMLZn_lAAAA\',\n matId: 5596a859240cbd3832123b26,\n reversed: 0,\n roomId: 5596a859e37d7e7099cec1e6,\n shuffled: 0,\n type: \'hand\',\n cards: [ 5596a859240cbd3832123b28, 5596a85c240cbd3832123b5d ],\n date: Fri Jul 03 2015 17:20:57 GMT+0200 (CEST),\n iscut: 0 }
usually, i can see a nice formated Json Object.
So, when i try :
console.log(pack.property) => undefined ...
anyone has had this problem ?
Thanks
Two parts to this one ...
First, the callback from a Mongoose find returns an array ... findOne will return a single object.
As far as the new lines go, mongoose documents have a toString() helper for console.log. It is likely adding the newlines for readability. Wrap the output in JSON.stringify (ie. console.log(JSON.stringify(pack))) prior to calling console.log and you will see the document as a string without the newlines. -http://mongoosejs.com/docs/api.html#document_Document-toString
find() returns an array, so use findOne(), thanks to Adam Wysocki.
Sometimes i'm stupid developper .
As Told Model.find() generates an array so here is how I approach the situation:
Kitten.find(function (err, kittens) {
if (err) return console.error(err);
kittens.forEach(function(kitten){
console.log(kitten.name);
});
});
This seems to me the most clear way to access the properties

accessing mongodb's object from mapper (MapReduce)

I have an extra question based on the one I asked before:
calculate frequency using mongodb aggregate framework
so my data in MongoDB looks like this now:
{
"data": {
"interaction": {
"created_at": "Wed, 09 Apr 2014 14:38:16 +0000"
}
},
"_id": {
"$oid": "53455b59edcd5e4e3fdd4ebb"
}
}
before I used to have it like:
[
{
created_at: "2014-03-31T22:30:48.000Z",
id: 450762158586880000,
_id: "5339ec9808eb125965f2eae1"
}
]
so to access created_at I was using mapper like:
var mapper = function () {
if ( this.created_at.getTime() > ( last_date + 10000 ) ) {
...
but as the structure in my database has changed, I tried to change:
this.created_at.getTime()
to:
this.data.interaction.created_at.getTime()
but unfortunately it didn't work out. Thank you for any help
Hate to make this that simple but all you want to do when importing these date strings is this:
new Date("Wed, 09 Apr 2014 14:38:16 +0000")
Which will return a proper date type that you actually should be inserting as part of your data.

Categories