无法分配给只读属性“winner”对象“[对象对象]”

发布于 2025-01-13 07:20:40 字数 6117 浏览 2 评论 0原文

遇到错误

ContestDetailsModalComponent.html:21 ERROR TypeError: Cannot assign to read only property 'winner' of object '[object Object]'
    at ContestDetailsModalComponent.onWinner (contest-details-modal.component.ts:88:24)
    at Object.eval [as handleEvent] (ContestDetailsModalComponent.html:21:17)
    at handleEvent (core.js:43993:77)
    at callWithDebugContext (core.js:45632:1)
    at Object.debugHandleEvent [as handleEvent] (core.js:45247:1)
    at dispatchEvent (core.js:29804:1)
    at core.js:42925:1
    at HTMLButtonElement.<anonymous> (platform-browser.js:2668:1)
    at ZoneDelegate.invokeTask (zone-evergreen.js:399:1)
    at Object.onInvokeTask (core.js:39680:1)

我尝试分配任务时

this.contest.winner = WinnerId;

您可以在以下代码片段中看到:

public onWinner(winnerId: number): void {
     const post: Post = new Post();
     post.title = `The winner of the contest has been elected: ${this.contest.title}`;
     post.description = `Tizio has been elected winner of the contest and ${this.user.name} gives him the most welcome compliments`;
     post.user = this.user;
     post.contest = this.contest;
     post.type = Type.WINNER;
     post.level = Level.SUCCESS;
     this.contest.winner = winnerId;
     this.store.dispatch(PostActions.savePost({post}));
     this.store.dispatch(ContestActions.saveContest({contest: this.contest}));
}

我已经与项目中的其他类一起完成了此类作业,但他们从未打扰过我。

我附上竞赛课程并发布它是否有用:

export class Contest {
  public id: number;
  public title: string;
  public description: string;
  public rules: string;
  public startDate: Date;
  public endDate: Date;
  public status: Status;
  public winner: number;
  public bannedUser: number[];
}


export class Post {
  public id: number;
  public title: string;
  public description: string;
  public level: Level;
  public type: Type;
  public user: User;
  public publishDate: Date;
  public contest: Contest;

}

我还尝试了在该论坛上始终找到的一些解决方案,例如:

Object.assign(目标,源);

但他正确地告诉我 this.contest.winner 为 null 或未定义。

我希望得到你的帮助。谢谢

编辑

这是 onWinner() 所在的整个 component.ts。

@Component({
  selector: 'app-contest-details-modal',
  templateUrl: './contest-details-modal.component.html',
  styleUrls: ['./contest-details-modal.component.scss'],
})
export class ContestDetailsModalComponent implements OnInit, OnDestroy, AfterViewChecked {
  private readonly subscriptions: Subscription = new Subscription();
  public id: number;
  public user: User;
  public contest: Contest;
  public images: Image[];
  public hasVoted: boolean;

  constructor(
    private readonly bsModalRef: BsModalRef,
    private readonly modalService: BsModalService,
    private readonly store: Store<AppState>,
    private cdRef: ChangeDetectorRef
  ) { }

  public ngOnInit(): void {

    this.subscriptions.add(this.store.pipe(select(AuthSelectors.getUser)).subscribe((user: User) => {
      if (user) {
        this.user = user;
      }
    }));

    this.subscriptions.add(this.store.pipe(select(ContestSelectors.getById)).subscribe((contest: Contest) => {
      if (contest) {
        this.contest = contest;
      }
    }));

    this.subscriptions.add(this.store.pipe(select(ImageSelectors.getImages)).subscribe((images: Image[]) => {
      if (images.length) {
        this.images = images;
      }
    }));

    this.subscriptions.add(this.store.pipe(select(UserSelectors.check)).subscribe((ack: Ack) => {
      if (ack) {
        this.store.dispatch(AuthActions.updatedUser({userId: this.user.id}));
        this.modalService.show(UploadImageModalComponent);
        this.bsModalRef.hide();
      }
    }));

    this.subscriptions.add(this.store.pipe(select(ImageSelectors.check)).subscribe((ack: Ack) => {
      if (ack) {
        this.bsModalRef.hide();
      }
    }));

  }

  public ngOnDestroy(): void {
    this.store.dispatch(UserActions.clean());
    this.store.dispatch(ContestActions.clean());
    this.subscriptions.unsubscribe();
  }

  public onWinner(winnerId: number): void {
    const post: Post = new Post();
    post.title = `The winner of the contest has been elected: ${this.contest.title}`;
    post.description = `Tizio has been elected winner of the contest and ${this.user.name} gives him the most welcome compliments`;
    post.user = this.user;
    post.contest = this.contest;
    post.type = Type.WINNER;
    post.level = Level.SUCCESS;
    this.contest.winner = winnerId;
    this.store.dispatch(PostActions.savePost({post}));
    this.store.dispatch(ContestActions.saveContest({contest: this.contest}));
  }

  public onJoin(): void {
    this.store.dispatch(UserActions.saveUser({idUser: this.user.id, id: this.contest.id}));
  }

  public onVote(image: Image): void {
    let vote: number = image.vote;
    vote = vote + 1;
    this.store.dispatch(ImageActions.updateImage({photoId: image.id, votes: vote, userId: this.user.id}));
    this.store.dispatch(AuthActions.updatedUser({userId: this.user.id}));
  }

  public isContain(contestId: number): boolean {
    if (this.user.myContest) {
      for (const i of this.user.myContest) {
        if (contestId === i) {
          return true;
        }
      }
    }
    return false;
  }

  public isImageVoted(id: number): boolean {
    if (this.user.favouritePhoto) {
      for (const imageVoted of this.user.favouritePhoto) {
            if (id === imageVoted) {
              this.hasVoted = true;
              return true;
            }
      }
      return false;
      }
   }

  public onBan(image: Image): void {
    this.modalService.show(BanModalComponent, {initialState : image});
    this.bsModalRef.hide();
  }

  public isBan(contestId: number): boolean {
    if (this.user.whereBanned) {
      for (const contestBanned of this.user.whereBanned) {
        if (contestId === contestBanned) {
          return true;
        }
      }
      return false;
    }
  }

  public ngAfterViewChecked(): void {
      this.cdRef.detectChanges();
  }
}

I'm encountering the error

ContestDetailsModalComponent.html:21 ERROR TypeError: Cannot assign to read only property 'winner' of object '[object Object]'
    at ContestDetailsModalComponent.onWinner (contest-details-modal.component.ts:88:24)
    at Object.eval [as handleEvent] (ContestDetailsModalComponent.html:21:17)
    at handleEvent (core.js:43993:77)
    at callWithDebugContext (core.js:45632:1)
    at Object.debugHandleEvent [as handleEvent] (core.js:45247:1)
    at dispatchEvent (core.js:29804:1)
    at core.js:42925:1
    at HTMLButtonElement.<anonymous> (platform-browser.js:2668:1)
    at ZoneDelegate.invokeTask (zone-evergreen.js:399:1)
    at Object.onInvokeTask (core.js:39680:1)

when I try to make the assignment

this.contest.winner = winnerId;

you see in the following code snippet:

public onWinner(winnerId: number): void {
     const post: Post = new Post();
     post.title = `The winner of the contest has been elected: ${this.contest.title}`;
     post.description = `Tizio has been elected winner of the contest and ${this.user.name} gives him the most welcome compliments`;
     post.user = this.user;
     post.contest = this.contest;
     post.type = Type.WINNER;
     post.level = Level.SUCCESS;
     this.contest.winner = winnerId;
     this.store.dispatch(PostActions.savePost({post}));
     this.store.dispatch(ContestActions.saveContest({contest: this.contest}));
}

I've done this kind of assignment with other classes around the project and they never bothered me.

I enclose the contest class and post if it is useful:

export class Contest {
  public id: number;
  public title: string;
  public description: string;
  public rules: string;
  public startDate: Date;
  public endDate: Date;
  public status: Status;
  public winner: number;
  public bannedUser: number[];
}


export class Post {
  public id: number;
  public title: string;
  public description: string;
  public level: Level;
  public type: Type;
  public user: User;
  public publishDate: Date;
  public contest: Contest;

}

I also tried some solutions always found on this forum such as:

Object.assign(target, source);

But he rightly tells me that this.contest.winner is null or undefined.

I hope for your help. Thank you

Edit:

This is the entire component.ts where onWinner() is present.

@Component({
  selector: 'app-contest-details-modal',
  templateUrl: './contest-details-modal.component.html',
  styleUrls: ['./contest-details-modal.component.scss'],
})
export class ContestDetailsModalComponent implements OnInit, OnDestroy, AfterViewChecked {
  private readonly subscriptions: Subscription = new Subscription();
  public id: number;
  public user: User;
  public contest: Contest;
  public images: Image[];
  public hasVoted: boolean;

  constructor(
    private readonly bsModalRef: BsModalRef,
    private readonly modalService: BsModalService,
    private readonly store: Store<AppState>,
    private cdRef: ChangeDetectorRef
  ) { }

  public ngOnInit(): void {

    this.subscriptions.add(this.store.pipe(select(AuthSelectors.getUser)).subscribe((user: User) => {
      if (user) {
        this.user = user;
      }
    }));

    this.subscriptions.add(this.store.pipe(select(ContestSelectors.getById)).subscribe((contest: Contest) => {
      if (contest) {
        this.contest = contest;
      }
    }));

    this.subscriptions.add(this.store.pipe(select(ImageSelectors.getImages)).subscribe((images: Image[]) => {
      if (images.length) {
        this.images = images;
      }
    }));

    this.subscriptions.add(this.store.pipe(select(UserSelectors.check)).subscribe((ack: Ack) => {
      if (ack) {
        this.store.dispatch(AuthActions.updatedUser({userId: this.user.id}));
        this.modalService.show(UploadImageModalComponent);
        this.bsModalRef.hide();
      }
    }));

    this.subscriptions.add(this.store.pipe(select(ImageSelectors.check)).subscribe((ack: Ack) => {
      if (ack) {
        this.bsModalRef.hide();
      }
    }));

  }

  public ngOnDestroy(): void {
    this.store.dispatch(UserActions.clean());
    this.store.dispatch(ContestActions.clean());
    this.subscriptions.unsubscribe();
  }

  public onWinner(winnerId: number): void {
    const post: Post = new Post();
    post.title = `The winner of the contest has been elected: ${this.contest.title}`;
    post.description = `Tizio has been elected winner of the contest and ${this.user.name} gives him the most welcome compliments`;
    post.user = this.user;
    post.contest = this.contest;
    post.type = Type.WINNER;
    post.level = Level.SUCCESS;
    this.contest.winner = winnerId;
    this.store.dispatch(PostActions.savePost({post}));
    this.store.dispatch(ContestActions.saveContest({contest: this.contest}));
  }

  public onJoin(): void {
    this.store.dispatch(UserActions.saveUser({idUser: this.user.id, id: this.contest.id}));
  }

  public onVote(image: Image): void {
    let vote: number = image.vote;
    vote = vote + 1;
    this.store.dispatch(ImageActions.updateImage({photoId: image.id, votes: vote, userId: this.user.id}));
    this.store.dispatch(AuthActions.updatedUser({userId: this.user.id}));
  }

  public isContain(contestId: number): boolean {
    if (this.user.myContest) {
      for (const i of this.user.myContest) {
        if (contestId === i) {
          return true;
        }
      }
    }
    return false;
  }

  public isImageVoted(id: number): boolean {
    if (this.user.favouritePhoto) {
      for (const imageVoted of this.user.favouritePhoto) {
            if (id === imageVoted) {
              this.hasVoted = true;
              return true;
            }
      }
      return false;
      }
   }

  public onBan(image: Image): void {
    this.modalService.show(BanModalComponent, {initialState : image});
    this.bsModalRef.hide();
  }

  public isBan(contestId: number): boolean {
    if (this.user.whereBanned) {
      for (const contestBanned of this.user.whereBanned) {
        if (contestId === contestBanned) {
          return true;
        }
      }
      return false;
    }
  }

  public ngAfterViewChecked(): void {
      this.cdRef.detectChanges();
  }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

野生奥特曼 2025-01-20 07:20:40

contest 包含对 Observable 发射的引用,并且 Observable 发射的所有引用都是只读的。要么克隆 contest

this.contest = { ...contest };

或者,更好的是,将其保留为 Observable 并按原样使用它,通常通过 async 管道。另外,如果您使用 NgRx,则需要使用 store.select()

this.contest$ = this.store.select(ContestSelectors.getById);

contest contains a reference to an Observable emission, and all references emitted by Observables are readonly. Either clone contest:

this.contest = { ...contest };

Or, better, leave it as an Observable and consume it as such, generally via the async pipe. Also, if you're using NgRx, you want to be using store.select():

this.contest$ = this.store.select(ContestSelectors.getById);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文