Hi!
I'm facing similar issue which is presented in here, but the proposed solution is not working for me. I'm using routing-controllers to perform the routing, and with it's JSON method, it fails to serialise ObjectID into string, which is why I'm using class-transformer.
However, when I'm trying to convert the ObjectID to a string in a way proposed in the earlier issue I mentioned. I get the following error:
TypeError: id.toHexString is not a function
at TransformMetadata.class_transformer_1.Transform [as transformFn] (/Users/max/Projects/backend-boilerplate/src/entity/User.js:18:46)
at /Users/max/Projects/backend-boilerplate/node_modules/class-transformer/TransformOperationExecutor.js:211:30
at Array.forEach (<anonymous>)
at TransformOperationExecutor.applyCustomTransformations (/Users/max/Projects/backend-boilerplate/node_modules/class-transformer/TransformOperationExecutor.js:210:19)
at _loop_1 (/Users/max/Projects/backend-boilerplate/node_modules/class-transformer/TransformOperationExecutor.js:155:41)
at TransformOperationExecutor.transform (/Users/max/Projects/backend-boilerplate/node_modules/class-transformer/TransformOperationExecutor.js:178:17)
at /Users/max/Projects/backend-boilerplate/node_modules/class-transformer/TransformOperationExecutor.js:33:41
at Array.forEach (<anonymous>)
at TransformOperationExecutor.transform (/Users/max/Projects/backend-boilerplate/node_modules/class-transformer/TransformOperationExecutor.js:30:19)
at ClassTransformer.classToPlain (/Users/max/Projects/backend-boilerplate/node_modules/class-transformer/ClassTransformer.js:9:25)
Without class-transformer, the JSON output looks like this
[
{
"id": {
"_bsontype": "ObjectID",
"id": {
"0": 90,
"1": 224,
"2": 40,
"3": 220,
"4": 11,
"5": 86,
"6": 132,
"7": 6,
"8": 66,
"9": 66,
"10": 231,
"11": 130
}
},
"username": "test"
},
...
]
I suspect this is issue where class-transformer fails to cast id as a Mongo ObjectId, because if I try to perform toHexString-function in the controller before it gets passed further, everything runs smoothly.
I'd however like to keep database level stuff in the model away from controller, which I see more like of more abstract layer: place for business logic.
See the code I'm using to reproduce and debug this issue more conveniently: https://bitbucket.org/vertics/typescript-typeorm-mongo-boilerplate/src
Possible duplicates / related issues:
https://github.com/typestack/class-transformer/issues/143
https://github.com/typestack/class-transformer/issues/87
I tried resolving this from the class-transformer repo code, but experimental features in TS were too much for me.
I copied a ObjectID toHexString implementation from BSON repo for my code that can be used in Transform
toHexString.ts
export default function(value) {
const hexTable = []
for (let i = 0; i < 256; i++) {
hexTable[i] = (i <= 15 ? '0' : '') + i.toString(16)
}
const id = Object.keys(value.id).map(key => value.id[key])
let hexString = ''
for (const el of id) {
hexString += hexTable[el]
}
return hexString
}
which can be then used in elsewhere like this
entity/User.ts
import {Transform} from 'class-transformer'
import {Column, Entity, ObjectID, ObjectIdColumn} from 'typeorm'
import toHexString from './../toHexString'
@Entity()
export class User {
@ObjectIdColumn()
@Transform(toHexString, {toPlainOnly: true})
public id: ObjectID
@Column()
public username: string
}
@Transform or @Type can help with this problem, but what if I can't use them? For example, if I have mongodb document without mapping. Can targetMaps in ClassTransformOptions help with that? I tried, but no luck
Using Transform is the right solution. I am closing this, as I see you have solved your issue.
This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.
Most helpful comment
I tried resolving this from the class-transformer repo code, but experimental features in TS were too much for me.
I copied a ObjectID toHexString implementation from BSON repo for my code that can be used in Transform
toHexString.ts
which can be then used in elsewhere like this
entity/User.ts