1

Before marking it as a duplicate: Read further carefully, I'm trying to update the DOC from the DOC itself. Not using a SCHEMA or MODEL. Therefore, any .findById* goes right out the window.

Here's what my schema currently looks like (only the related section):

let UserAccSchema = new Schema({
meta : {
accessControl: {
authTokens:[{
    issuedOn: {
        type: Date,
        default: Date.now()
    },
    expiresOn: {
        type: Date,
        default: Date.now() + 1728000000 //Defaults to 20-days
    },
    lastUsage: {
        type: Date,
        default: Date.now()
    },
    authAgent: {
        type: String,
        default: "default"
    }
}]}}
});

I want to push a new object in "meta/accessControl/authTokens". My current approach is:

UserAccSchema.methods.generateAuthToken = function (authAgent, cb) {
    console.info("MongoUser | Auth | Attempting to generate auth token for user | " + this._id);
    this.update({
        $push: {
            "meta.accessControl.authTokens": {
                authAgent: authAgent
            }
        }
    }, {safe: true, new: true, upsert:true}, function (err, obj) {
        if (err) {
            console.error("MongoUser | Auth | Error occurred while saving auth-token information | " + err);
            cb(new AppError("Auth token cannot be generated. Please try again.", AppError.ErrorCode.INTERNAL_SERVER_ERROR));
        } else {
            console.info("MongoUser | Auth | Auth token for user was generated | " + JSON.stringify(obj));
            cb(null, obj);
        }
    });
};

the above code is doing the job, but the problem that I'm having is when pushing the new object, the new object doesn't gets returned in:

function(err,obj) {

}

Instead returns this:

{"n":1,"nModified":1,"ok":1}

What I want to know:

  • Where Am I wrong?
  • Am I doing this the right way? Any other way to $push the obj?

Thank You

AnkitNeo
  • 122
  • 1
  • 11
  • `.update` returns number of modified documents, not the object – parwatcodes Apr 15 '17 at 13:46
  • Please take a look. http://stackoverflow.com/questions/31808786/mongoose-difference-of-findoneandupdate-and-update – s7vr Apr 15 '17 at 13:48
  • @pk08 That's why I want to know, is there any other way to do this in order to get the updated part. – AnkitNeo Apr 15 '17 at 13:49
  • @Veeram That too, I've already checked it out. I want the updated part (in my case, the object I just pushed into my original doc) to be returned, not the whole doc. – AnkitNeo Apr 15 '17 at 13:56
  • Here you go.. http://stackoverflow.com/questions/35946989/how-to-get-back-the-new-value-after-an-update-in-a-embedded-array/35947329#35947329 You need to use projection with elemMatch to get the updated embedded object back. – s7vr Apr 15 '17 at 13:57
  • @Veeram Thanks for the reply. This one looks interesting. I'll give this one a go. Doesn't much helps my original question though, as I want this to happen over DOCUMENT not SCHEMA – AnkitNeo Apr 15 '17 at 14:00
  • Np. Not sure what you mean with DOCUMENT not SCHEMA part here The example over there is in mongodb query you've to convert it into mongoose. – s7vr Apr 15 '17 at 14:02
  • @Veeram You are not getting the point. This is happening inside one of the Schema.method. Therefore, I already have the doc that I want to update. Your approach (and all others) want me to find the doc via the model and then execute findByIdAndUpdate. Now why'd I wanna do that if I already have the doc? – AnkitNeo Apr 15 '17 at 14:19
  • Sorry I'm not really familiar with mongoose. Why not just check the response `{"n":1,"nModified":1,"ok":1}` and return the `authAgent` back ? Its new entry and you just send that object which is what gets persist in database. – s7vr Apr 15 '17 at 15:13
  • Whole doc. That is the main problem – AnkitNeo Apr 15 '17 at 15:16
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/141777/discussion-between-veeram-and-ankitneo). – s7vr Apr 15 '17 at 15:17
  • Possible duplicate of [How to get back the new value after an update in a embedded array?](http://stackoverflow.com/questions/35946989/how-to-get-back-the-new-value-after-an-update-in-a-embedded-array) – KARTHIKEYAN.A Apr 15 '17 at 18:04
  • @KARTHIKEYAN.A Please read the comments above. Clearly stated, not MODEL, it's DOCUMENT. At least read the question carefully before marking it as a possible duplicate. – AnkitNeo Apr 15 '17 at 18:35

2 Answers2

1

.update Only returns the modified number of documents

as {"n":1,"nModified":1,"ok":1}

to return the modified documents you can use findOneAndUpdate

like db.foo.findOneAndUpdate({class: 3}, {$set:{name: 231}}, {new: true}) will return the response as

{
    "_id" : ObjectId("58db5f4a611f51a2bf08bbb0"),
    "name" : "parwat",
    "class" : 3
}
parwatcodes
  • 6,669
  • 5
  • 27
  • 39
0
UserAccSchema.methods.generateAuthToken = function (authAgent, cb) {
    console.info("MongoUser | Auth | Attempting to generate auth token for user | " + this._id);
    this.findOneAndUpdate({_id: this._id}, {$set:{
            "meta.accessControl.authTokens": {
                authAgent: authAgent
            }}, {new: true}, function (err, obj) {
        if (err) {
            console.error("MongoUser | Auth | Error occurred while saving auth-token information | " + err);
            cb(new AppError("Auth token cannot be generated. Please try again.", AppError.ErrorCode.INTERNAL_SERVER_ERROR));
        } else {
            console.info("MongoUser | Auth | Auth token for user was generated | " + JSON.stringify(obj));
            cb(null, obj);
        }
    });
};
KARTHIKEYAN.A
  • 18,210
  • 6
  • 124
  • 133