Open fyn-dev opened 6 years ago
First thing's first, the @Property
decorator's first argument is the type of the property, so in your case it should be @Property(String)
to ensure that things are validated correctly.
As for renaming properties, you're going to want to use the @Transform
decorator for that. Since you're renaming a top-level property, you'll need to transform the object one level above it (the document). Let's quickly build a decorator which leverages the @Transform
decorator to accomplish this for any given field on your document.
export function RenameProperties(map: { [codeField: string]: string }) {
return Iridium.Transform(db => {
for (const codeField in map) {
const dbField = map[codeField]
db[codeField] = db[dbField]
delete db[dbField]
}
return db
}, code => {
for (const codeField in map) {
const dbField = map[codeField]
code[dbField] = code[codeField]
delete code[codeField]
}
return code
})
}
This would allow you to rename your property like this:
@Collection("houses")
@RenameProperties({
houseName: "house_name"
})
export class House extends Instance<HouseDocument, House> implements HouseDocument {
@ObjectID
public _id: string;
@Property(String)
public houseName: string;
}
Please let me know if you run into any problems with that approach.
Regards, Benjamin
@SPARTAN563 thanks! This may work, but it looks like no standard decorator like @RenameProperty/@MapProperty in the library itself.
@SPARTAN563 after some tested this code doesn't work properly it throw this error
Expected houseName to be a defined non-null value but got undefined instead
If I set @Property(String, false) then no issue, but how to apply @Property decorator to field which will be renamed in db to another one?
I'm sorry about that @fyn-dev, I had completely forgotten about that little quirk.
The issue is caused by the way that the schema is used to build the proxy instance (which forwards requests for houseName
to the underlying document.houseName
while doing transforms on the field). As a result, you end up needing both fields to be present in the schema (with the code field set to not-required) for this to work. All round, not a great experience.
I've instead opted to expand the underlying Iridium Instance type to support renaming natively through a new Instance.renames
field (and a corresponding @Iridium.Rename()
decorator).
You should now be able to simply do the following (without any extra code) using v8.0.0-alpha.10
.
@Collection("houses")
export class House extends Instance<HouseDocument, House> implements HouseDocument {
@ObjectID
public _id: string;
@Property(String)
@Rename("house_name")
public houseName: string;
}
Please let me know if you run into any issues with it, and sorry about the slow turnaround time on this (holidays got in the way).
@SPARTAN563 Thanks a lot really nice feature to have!
Let's say in my document I have this structure:
but in my code I want to map like this:
problem is when I try for example insert new document is saving as houseName property but not as house_name. How to insert data using house_name but keep in the code houseName property?
TypeScript version 2.6.2 Iridium version 8.0.0-alpha.5