4

我的 Angular 应用程序中有一些打字稿类实例,我必须保存到 firebase。Firebase 不支持自定义类,所以我发现了这个:https ://github.com/typestack/class-transformer这似乎很适合我。

所以现在我正在创建我的对象,并尝试转换它。

这是我的对象。

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;
}

我正在创建一个“旅行”并尝试对其进行转换:

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)

但我明白了:

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)

我刚刚创建的对象: 在此处输入图像描述

我想要么我的对象处于不正确的状态,要么我的定义很差,但我找不到什么?

4

1 回答 1

2

错误在于 的定义Itinerary,更具体地说this.steps = Step[0];,将变量设置为未定义的代码行很可能不是故意的。该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();
  }
}

更多细节: 由于在属性上使用了鉴别器,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;
    }

链接到 github

Step[0]未定义最终导致这条线subValue.constructor崩溃。

于 2021-03-15T17:00:56.500 回答