javascript - Having issues updating a document thats retrieved using a Mongoose model and processed as a promise -
jump update #2 closer detail
im having issues simple update document retrieved querying container via mongoose model. find query have 2 populations, other that, im not sure issue be
the problem i'm running into, when retrieve document, update property, attempt save updates document via mongooses doc.save() method, nothing seems happen. whats weird, save() doesn't fire off callback passed it.. (or fire off then() or catch() if handle promise)
model: asset
module.exports = mongoose => { const schema = mongoose.schema const assetschema = new schema({ attributes: [{ _field: { type: schema.types.objectid, ref: 'field', required: true }, value: { type: schema.types.mixed, required: true } }], _partition: { type: schema.types.objectid, ref: 'partition' } }) return mongoose.model( 'asset', assetschema ) } and detail, heres example result same find query same 2 populations
[ { "_id" : objectid("56b626dc4040b5383696d16f"), "_partition" : { _fields: [object], name: 'server stuff', _id: objectid("56ae4707f3d4645b2e5b0537") }, "attributes" : [ { _field: { _id: objectid("56ae4703f3d4645b2e5b0534"), name: 'hostname' }, value: 'server-04.foobar.ad', _id: objectid("56b626dc4040b5383696d172") } ] } ] document query
heres code example of retrieve documents via foo.find method (which works), , update value of first attribute (which works), when try a.save() doc.. nothing happens:
asset .find( { _id: '56b6568cb5195902381f6c65' } ) .populate( { path: 'attributes._field' } ) .populate( { path: '_partition' } ) .then( docs => { if( ! docs ) throw new error(`no docs found`) console.log('# docs found:', docs.length) // 1 console.log('# instance?:', docs[0] instanceof asset) // true console.log('# docs:', assets) // shows single document inside array let = docs[0] a.attributes[0].value = 'blah' // problem is, nothing below here displayed in console a.save(function (err) { if (err) throw new error('failed update:' + err) console.log('updated!') }) } ) .catch( err => console.error( 'error:',err ) ) .finally( () => mongoose.connection.close() ) in console, displays expected, right until a.save().. neither error or updated! displayed.
it's mongoose document i'm interacting (the a instanceof foo shows true), i'm not @ sure why save() isn't doing anything..
i tried handle a.save() promise, instead of handing callback it, , again, nothing happened @ all, neither then or catch executed.
this driving me crazy!! im sure stupid i've overlooked, cant seem find it. appreceated
p.s. didn't include partition or field models/schemas because highly doubt related... if thinks so, let me know
p.s.s. fyi, mongodb user does have write access
update #1
per suggestion @johnnyhk, tried execute doc.markmodified():
asset .find( { _id: '56b6568cb5195902381f6c65' } ) .populate( { path: 'attributes._field' } ) .populate( { path: '_partition' } ) .then( docs => { if( ! docs ) throw new error(`no docs found`) console.log('# docs found:', docs.length) // 1 console.log('# instance?:', docs[0] instanceof asset) // true console.log('# docs:', assets) // shows single document inside array let = docs[0] a.attributes[0].value = 'blah' a.markmodified('attributes') // problem is, nothing below here displayed in console a.save(function (err) { if (err) throw new error('failed update:' + err) console.log('updated!') }) } ) .catch( err => console.error( 'error:',err ) ) .finally( () => mongoose.connection.close() ) no changes... nothing in a.save() displayed in console, , doc isn't updated
update #2
after tinkering.. seems related being promise..
this successful:
// callback asset.find( { _id: '56b6568cb5195902381f6c65' } ) .populate( { path: 'attributes._field' } ) .populate( { path: '_partition' } ) .exec(function (err, doc) { if (err) throw new error(err) doc[0].attributes[0].value = 'foo' doc[0].save(function (err) { if (err) throw new error(err) console.log('updated to:',doc[0]) mongoose.connection.close() }) }) this unsuccessful:
// promise import promise 'bluebird' mongoose.promise = promise // .. asset.find( { _id: '56b6568cb5195902381f6c65' } ) .populate( { path: 'attributes._field' } ) .populate( { path: '_partition' } ) .then( doc => { doc[0].attributes[0].value = 'foo' doc[0].save(function (err) { if (err) throw new error(err) console.log('updated to:',doc[0]) }) }) .catch( err => { throw new error(err) }) .finally( () => mongoose.connection.close() ) the difference can think of promise, opposed callback
whats super weird... of code inside .then() executes.. not save()
update #3
i created github issue, , per last update..
i found this issue, "solution" downgrade entire major version, 4.x 3.x...
the version im @ ^4.3.7, tried change 3.8.35, downgrade went fine script threw bunch of errors... honestly, id rather not use such old version anyways.
i replicated issue having using schema have provided , found solution. following worked me , updated .value property. try prepending return doc[0].save() return mentioned in this article
var mongoose = require('mongoose'); mongoose.promise = require('bluebird'); // ..... asset.find( { _id: '56b6568cb5195902381f6c65' } ) .populate( { path: 'attributes._field' } ) .populate( { path: '_partition' } ) .exec() // queries aren't full-fledged promises! .then( doc => { console.log('before:',doc[0]); doc[0].attributes[0].value = 'foo' // return promise! return doc[0].save(function(err){ console.log('updated to:', doc[0]); }); }) .catch( err => { throw new error(err) }) .finally( () => mongoose.connection.close() ) i use .exec() because according docs queries aren't full-fledged promises (just in case). since .save() returns promise, should return promises resolve sequentially; waiting until previous promises complete before executing. posted code here
Comments
Post a Comment