无法分配给只读属性“winner”对象“[对象对象]”
遇到错误
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 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
contest
包含对 Observable 发射的引用,并且 Observable 发射的所有引用都是只读的。要么克隆contest
:或者,更好的是,将其保留为 Observable 并按原样使用它,通常通过
async
管道。另外,如果您使用 NgRx,则需要使用store.select()
:contest
contains a reference to an Observable emission, and all references emitted by Observables are readonly. Either clonecontest
: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 usingstore.select()
: