Reputation: 499
get list with Input
in my components :
@Input() usersInput: Section[];
export interface Section {
displayName: string;
userId: number;
title: number;
}
and this is the value list :
0:
displayName: "بدون نام"
firstName: null
lastName: null
title: 0
userId: 1
1:
displayName: "محمدامین چهاردولی"
firstName: "محمدامین"
lastName: "چهاردولی"
title: 0
userId: 2
in ngAfterViewInit
i set the input Value to users List :
ngAfterViewInit(): void {
this.users = this.usersInput;
if (this.users.length === 0) {
this.show = false;
} else {
this.show = true;
}
}
this is Users :
users: Section[] = [];
and i use it in html List :
<div *ngFor="let item of users" class="d-flex selected-list-items mt-3">
<div class="col-md-5 col-lg-5 col-xs-5 col-sm-5 col-xl-5">
<label>{{item.displayName}}</label>
</div>
<div class="col-md-5 col-lg-5 col-xs-5 col-sm-5 col-xl-5">
<label> {{ getEnumTranslate(item.title)}}</label>
</div>
<div class="justify-content-center col-md-2 col-lg-2 col-xs-2 col-sm-2 col-xl-2">
<button (click)="deleteUser(item.userId)" mat-button>
<mat-icon aria-label="Delete" color="accent">delete</mat-icon>
</button>
</div>
</div>
now when i need to use delete button :
<button (click)="deleteUser(item.userId)" mat-button>
<mat-icon aria-label="Delete" color="accent">delete</mat-icon>
</button>
ts :
deleteUser(id: number): void {
let userModel = {} as Section;
userModel = this.users.find(x => x.userId === id);
const index = this.users.indexOf(userModel);
this.users.splice(index, 1);
this.emitValueModel.push(
{
title: this.user.title,
userId: this.user.userId
}
);
this.selectedUserId.emit(this.emitValueModel);
if (this.users.length === 0) {
this.show = false;
}
this.cdref.detectChanges();
}
it show me this error :
ERROR TypeError: Cannot delete property '1' of [object Array]
whats the problem??? how can i solve that ?
Upvotes: 24
Views: 46196
Reputation: 2389
I ran across this issue in my React app, but assume the same issue is occurring here, in Angular. The reason for the error was that I was making a shallow copy via the JS spread operator.
const newArr = [...oldArr];
newArr.splice(1) // Remove all items except for the first one.
// This would throw the error `Cannot delete property '1' of [object Array]`
The solution was to install lodash.clonedeep and perform a deep clone.
import cloneDeep from "lodash.clonedeep";
const newArr = cloneDeep(oldArr);
newArr.splice(1) // Remove all items except for the first one.
// Success!
Upvotes: 6
Reputation: 37
This article states what you have to do to solve this. Basically, you have to specify that the element of the index in the array you want to delete is configurable. So you just have to state
Object.defineProperty( array , index you want to delete, { configurable : true } );
Upvotes: 3
Reputation: 264
I've faced the same issue and according to this article the problem is that user array has non configurable properties. I suppose angular Inputs are set as non configurable. When you do:
this.users = this.usersInput
you simply pass the reference of input to this.users
.
The solution is to simply copy input array before splicing. In your case:
this.users = [...this.usersInput];
Btw. do it in deleteUser method instead of afterViewInit with local variable. You do not need two class props referring to the same object.
Upvotes: 18
Reputation: 22213
Try:
deleteUser(id) {
const index = this.users.findIndex(x => x.userId === id);
this.users.splice(index, 1);
}
Upvotes: 2