uon-team / db

MongoDB module for @uon/core server applications
MIT License
0 stars 0 forks source link

Unable to set an object reference normally #3

Closed sdalexandre closed 2 years ago

sdalexandre commented 3 years ago

In the model of a specific class I have this:

@Member()
owner: User;

At the insertion I can set this member and it will get something like this: owner: ObjectId("612fe89ad0e6bf73608c6504")

But if I set it during an update with the following code:

let result = await this.dbContext.updateOne(dbsub, {
    $set: {owner: new User(userId)}
});

I get something like this:

"owner" : {
    "id" : "612fe89ad0e6bf73608c6504",
    "registered" : null,
    "fullName" : null,
    "email" : null,
    "phone" : null,
    "password" : null,
    "mailingList" : null,
    "emailPreferences" : null,
    "lang" : null,
    "createdOn" : null,
    "registeredOn" : null,
    "updatedOn" : null,
    "roles" : null,
    "stripeCustomerId" : null,
    "isDeleted" : null
}   

And any subsequent query to the collection where the "owner" is set like this I'am getting then the following error:

TypeError: id.toHexString is not a function
    at ID_TO_STRING (webpack:///./node_modules/@uon/db/db.context.js?:663:33)
    at CastIdsAsRefs (webpack:///./node_modules/@uon/db/db.context.js?:654:40)
    at eval (webpack:///./node_modules/@uon/db/db.context.js?:121:74)
    at Array.map (<anonymous>)
    at DbContext.eval (webpack:///./node_modules/@uon/db/db.context.js?:121:38)
    at Generator.next (<anonymous>)
    at fulfilled (webpack:///./node_modules/tslib/tslib.es6.js?:95:58)
    at processTicksAndRejections (internal/process/task_queues.js:95:5)

The workaround for now is using a NativeId() instead. But it can't be used directly because of the type validation don't allow this:

let result = await this.dbContext.updateOne(dbsub, {
    $set: {owner: new NativeId(userId)}
});

Instead, I'm forced to do it using an "any" type like this:

let setField: any = {
    owner: new NativeId(userId)
};

let result = await this.dbContext.updateOne(dbsub, {
    $set: setField
});
uon-io commented 2 years ago

The problem here is that the library does not yet transform the extra update operation passed to context.updateOne(). It is something that I've been planning to add, but now for this case you can simply assign a User instance to the owner field and call updateOne without any extra parameter

dbsub.owner = new User(userId);
let result = await this.dbContext.updateOne(dbsub);

Assignment marks the field as "dirty" so will result in the following update op:

{
    $set: { owner: ObjectId(...) }
}

I will update this issue once I implement the extra ops transformation.

uon-io commented 2 years ago

This has been fixed in commit 768f94a736298caf5fdd641b86d08e6e13dcbce4 It will be updated on NPM shortly.