Merge request #1702 broke functionality of extended operators in updateAll operation on the models.
The new line added in dao.js here stores in ctx.data the object representation of the created instance from the above line, so this is the final value passed in the connector update method which handles the data update.
This has the effect that any passed extended operators such as in MongoDB $set is stripped from the update data because .toObject does not take into account any extended operators that might have been given in the update data, which is referenced here: https://loopback.io/doc/en/lb3/MongoDB-connector.html
So basically you cannot use extended operators in updateAll function.
To find out the result just issue an update on a model that has enabled the use of allowExtendedOperators such as Model.updateAll({}, { $set: { prop: 'sth'} })
It should pass the given extended operators in the update object and let the MongoDB Connector handle them appropriately.
linux x64 10.15.3
├── [email protected]
├── [email protected]
@b-admike , could you please take a look? Thanks.
hi @mitsos1os thank you for your detailed description. I was looking through the codebase and I wrote a quick test to try to verify what you observed:
it.only('should allow extended operators in update data', function() {
let noteModel = db.define('noteModel', {
title: String,
description: String,
});
noteModel.settings.mongodb = {allowExtendedOperators: true};
let noteId;
return noteModel.create({title: 'note1', description: 'grocery list'})
.then(function(createdInstance) {
noteId = createdInstance.id;
return noteModel.updateAll({id: noteId}, {description: 'updated list', $set: {title: 'setTitle'}});
})
.then(function() {
return noteModel.findById(noteId);
})
.then(function(foundNote) {
foundNote.title.should.equal('setTitle');
foundNote.description.should.equal('updated list');
});
});
Here is what the connector method update/updateAll receives for data object with the current changes:
Object {description: "updated list", $set: Object}
$set:Object {title: "setTitle"}
description:"updated list"
should:Assertion
__proto__:Object {constructor: , __defineGetter__: , __defineSetter__: , …}
without the change:
Object {description: "updated list", $set: Object}
$set:Object {title: "setTitle"}
description:"updated list"
should:Assertion
__proto__:Object {constructor: , __defineGetter__: , __defineSetter__: , …}
So, I do not see any change in behaviour by adding the line ctx.data = inst.toObject(true); for this use case. Is the test case correct in doing what you described? Have you set the allowExtendedOperators setting?
_EDIT_: the test case passes for both with and without the change in juggler.
@b-admike Thanks for looking into it.
Your test is correct. Two additions:
strict option enabled (Forgot to mention it sorry...), so you can also add the line: noteModel.settings.strict = true;noteModel.updateAll({id: noteId}, {$set: {description: 'updated list', title: 'setTitle'}})WIth these changes you will be able to see the problem
@mitsos1os @b-admike, after @b-admike has made a new release for juggler and mongodb connector last week, is the problem resolved?
@dhmlau Since #1726 was merged we should be all right yes
@mitsos1os, thanks for the confirmation. Let me close this issue as resolved. Thanks!
Most helpful comment
@mitsos1os, thanks for the confirmation. Let me close this issue as resolved. Thanks!