[英]How to convert typescript class to plain javascript object with class-transformer
I've some typescript classes instances in my angular app that I've to save to firebase.我的 angular 应用程序中有一些 typescript 类实例,我必须保存到 firebase。 Firebase isn't supporting custom classes, so I found this: https://github.com/typestack/class-transformer that seems well fitted for me. Firebase 不支持自定义类,所以我发现这个: https://github.com/typestack/class-transformer似乎很适合我。
So now I'm creating my object, and trying to convert it.所以现在我正在创建我的 object,并尝试对其进行转换。
Here is my object.这是我的 object。
export class Trip {
id: string;
owner: string;
name: string;
@Type(() => Date)
startDate: Date;
@Type(() => Date)
endDate: Date | undefined;
coverImageUrl: string;
@Type(() => Itinerary)
itinerary: Itinerary;
constructor() {
this.itinerary = new Itinerary();
}
}
export class Itinerary {
@Type(() => ItineraryStats)
stats: ItineraryStats;
@Type(() => Step, {
discriminator: {
property: '__type',
subTypes: [
{ value: ActivityStep, name: 'ActivityStep' },
{ value: NightStep, name: 'NightStep' },
{ value: PointOfInterest, name: 'PointOfInterest' },
{ value: TravelStep, name: 'TravelStep' },
],
},
})
steps: Step[];
constructor() {
this.steps = Step[0];
this.stats = new ItineraryStats();
}
}
export class ItineraryStats {
///In days
duration: number;
//in hours
driveTime: number;
//in kilometers
driveDistance: number;
averageDriveDistancePerDay(): number {
return this.driveDistance / this.duration;
}
averageDriveTimePerDay(): number {
return this.driveTime / this.duration;
}
}
export abstract class Step {
@Type(() => Date)
start: Date;
@Type(() => Date)
end: Date;
duration: number;
enforcedStartStop: boolean;
warning: string;
}
export class ActivityStep extends StopStep {
duration: number;
constructor() {
super();
this.id = Guid.newGuid();
}
}
export class NightStep extends StopStep {
nightNumber: number;
numberOfNight: number;
}
export class PointOfInterest {
@Type(()=>PointOfInterest)
type: PointOfInterest;
}
export class TravelStep extends Step {
@Type(() => TravelMode)
Mode: TravelMode;
PolyLines: string;
}
I'm creating one "trip" and trying to convert it:我正在创建一个“旅行”并尝试对其进行转换:
const trip = new Trip();
trip.owner= firebase.auth().currentUser.uid;
trip.name= action.name;
trip.startDate = action.startDate,
trip.endDate = action.endDate;
console.log(trip);
const converted = classToPlain(trip)
But I get this:但我明白了:
ERROR TypeError: Cannot read property 'constructor' of undefined
at TransformOperationExecutor.js:207
at Array.find (<anonymous>)
at TransformOperationExecutor.transform (TransformOperationExecutor.js:207)
at TransformOperationExecutor.transform (TransformOperationExecutor.js:266)
at ClassTransformer.classToPlain (ClassTransformer.js:10)
at classToPlain (index.js:8)
at Object.toFirestore (trips.firestore.ts:16)
at ma (index.cjs.js:15983)
at n.set (index.cjs.js:15359)
at AngularFirestoreDocument.set (angular-fire-firestore.js:512)
The object I just created:我刚刚创建的 object:
I guess either my object is in an improper state or I've something poorly defined, but I can't find what?我猜我的 object 是不正确的 state 或者我的定义不明确,但我找不到什么?
The error lies in the definition of Itinerary
, more specifically the code line this.steps = Step[0];
错误在于Itinerary
的定义,更具体地说是代码行this.steps = Step[0];
which sets the variable to undefined and most likely wasn't intentional.它将变量设置为未定义,很可能不是故意的。 The class-transformer
library can deal with property steps
being an empty array, array of steps, or not existing in the first place but crashes when the value is set to undefined. class-transformer
器库可以处理属性steps
是一个空数组、步骤数组或首先不存在但当值设置为未定义时崩溃。
export class Itinerary {
@Type(() => ItineraryStats)
stats: ItineraryStats;
@Type(() => Step, {
discriminator: {
property: '__type',
subTypes: [
{ value: ActivityStep, name: 'ActivityStep' },
{ value: NightStep, name: 'NightStep' },
{ value: PointOfInterest, name: 'PointOfInterest' },
{ value: TravelStep, name: 'TravelStep' },
],
},
})
steps: Step[];
constructor() {
// Step[0] causes the crash, because its undefined, either dont set it or
// set it to this.steps = []
this.steps = Step[0];
this.stats = new ItineraryStats();
}
}
More details: Due to the use of discriminators on property steps
the corresponding logic kicked in and compared the constructors defined under subTypes
, with the constructor of the current value to find the correct subtype name:更多细节:由于在属性steps
上使用了鉴别器,相应的逻辑启动并将subTypes
下定义的构造函数与当前值的构造函数进行比较以找到正确的子类型名称:
if (this.transformationType === TransformationType.CLASS_TO_PLAIN) {
subValue[targetType.options.discriminator.property] = targetType.options.discriminator.subTypes.find(
subType => subType.value === subValue.constructor
).name;
}
Step[0]
being undefined eventually made this line subValue.constructor
crash. Step[0]
未定义最终使这一行subValue.constructor
崩溃。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.