DanHeidel DanHeidel - 5 months ago 68
Node.js Question

I can't modify an array in Node

I'm trying to make some modifications to a data array returned from a mongoose/MongDB query. However, I can't seem to make any changes to the array. Am I missing something obvious here?

function stdSend(err, data, res){
if(err){
console.log(err);
res.send(err);
}else{
console.log('rows returned: ' + data.length);
for(var rep=0;rep<data.length;rep++){
var foo = new Date(data[rep].timestamp);
console.log(Object.isFrozen(data[rep])); <- false
console.log(Object.isSealed(data[rep])); <- false
data[rep].test = 'test'; <- test not added to data[rep]
data[rep].timestamp = foo; <- timestamp not modified
console.dir(data[rep]);
}
//console.log(data);
res.send(data);
}
}


stdSend is being called from the Mongoose .exec function as the callback. The callback works fine and the data goes to the browser after I feed it to res.send in Express. However, I wanted to do some quick bug-testing by converting the data[].timestamp values into standard datetime values before sending it out.

However, everything I've tried to change the values of data have failed. The data[rep].test = 'test' fails to add a test property to data and the attempt to modify timestamp also fails. Both isFrozen and isSealed return false.

Any ideas what's going on here?

Edit:
I think there's some confusion about what I'm asking here. I am not writing the data to the database. This is an object array returned from the DB query that I am trying to modify. The returned object is below:

[ { name: 'scishow',
timestamp: 1380154343818,
funding: 42,
subs: 3500 },
{ name: 'scishow',
timestamp: 1380240748329,
funding: 42,
subs: 3520 },
{ name: 'scishow',
timestamp: 1380327152521,
funding: 42,
subs: 3554 },
{ name: 'scishow',
timestamp: 1380413558026,
funding: 43,
subs: 3579 },
{ name: 'scishow',
timestamp: 1380585807946,
funding: 43,
subs: 3638 },
{ name: 'scishow',
timestamp: 1384300959056,
funding: 52,
subs: 5 },
{ name: 'scishow',
timestamp: 1384560752617,
funding: 53,
subs: 5 },
{ name: 'scishow',
timestamp: 1384646717448,
funding: 53,
subs: 5 },
{ name: 'scishow',
timestamp: 1384819280960,
funding: 53,
subs: 5 },
{ name: 'scishow',
timestamp: 1385251243369,
funding: 53,
subs: 5753 },
{ name: 'scishow',
timestamp: 1385338257810,
funding: 53,
subs: 5779 } ]

Answer Source

If data is the result of a Mongoose query, it's not an array of plain JS objects, but an array of document instances. They may look like proper JS objects, but you can't treat them as such.

You need to convert those documents to proper JS objects before you can change them:

for (var rep = 0; rep < data.length; rep++) {
  var doc = data[rep].toObject();
  var foo = new Date(doc.timestamp);
  doc.test = 'test';
  doc.timestamp = foo;
  console.dir(doc);
}

Alternatively, you can add { strict: false } to your schema (as @HenryLeu suggested) and use .set() on the documents to add properties:

data[rep].set('test', 'test');

Or without changing your schema:

data[rep].set('test', 'test', { strict: false });
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download