I notice that the @Mapfield does not support mapping the submaps
export class SubMap {
name: string
age: number
}
@Entity()
export class MapItem {
@ID()
id: string
@MapField()
map: SubMap
@MapField(SubMap)
mapList: SubMap[]
}
In this example even if I annotate the SubMap as an Entity it does not map to a SubMap. I tinkered with the code and came up with a function that can recursively map sub entities.
private mapFromField(field: PropertyMetadata, data: any): any {
const meta = Metadata.entity(field.constructor).get()
if (!meta) {
// There is no metadata known for this field type so we will just return it as an anonymous/untyped object.
return Object.assign(new field.constructor(), data[field.name])
}
let entity = new field.constructor()
const fields = meta.fields
fields.forEach(field => {
if (data[field.name] === undefined) {
return
} else if (
(data[field.name]?.toDate !== undefined && typeof data[field.name]?.toDate === 'function') ||
(typeof data[field.name] === 'object' && data[field.name]?.constructor?.name === 'Timestamp')
) {
entity[field.name] = data[field.name]?.toDate()
} else if (field?.isDate && data[field.name] && data[field.name]?.length > 0) {
try {
entity[field.name] = new Date(data[field.name])
} catch (error) {
console.error(error)
}
} else if (
typeof data[field.name] === 'object' &&
field?.isMap &&
(typeof field?.constructor === 'object' || typeof field?.constructor === 'function')
) {
if (Array.isArray(data[field.name])) {
entity[field.name] = data[field.name].map(obj => Object.assign(new field.constructor(), obj))
} else {
console.log(field.name)
entity[field.name] = this.mapField(field, data[field.name])
}
} else {
entity[field.name] = data[field.name]
}
})
return entity
}
and then the inverse:
private fieldToMap(field: PropertyMetadata, entity: any): any {
const meta = Metadata.entity(field.constructor).get()
if (!meta) {
// There is no meta for this field so just return the destructured value
return { ...entity }
}
const fields = meta.fields
let dataToSave = {}
fields.forEach(field => {
if (field?.isDate && field?.updateOnSave) {
let date = new Date()
entity[field.name] = date
dataToSave[field.name] = date
} else if (field?.isDate && field?.generateOnCreate && (entity?.__ormOnFire?.isNew || entity.__ormOnFire === undefined)) {
let date = new Date()
entity[field.name] = date
dataToSave[field.name] = date
} else if (field?.isMap && Array.isArray(entity[field.name])) {
dataToSave[field.name] = entity[field.name].map(obj => {
return { ...obj }
})
} else if (field?.isMap) {
dataToSave[field.name] = this.fieldToMap(field, entity[field.name])
} else {
dataToSave[field.name] = entity[field.name]
}
})
return dataToSave
}
Is this something you want me to complete and incorporate upstream?
I notice that the @Mapfield does not support mapping the submaps
In this example even if I annotate the SubMap as an Entity it does not map to a SubMap. I tinkered with the code and came up with a function that can recursively map sub entities.
and then the inverse:
Is this something you want me to complete and incorporate upstream?