24

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 ?

4
  • 2
    There's .findIndex() (instead of .find() + .indexOf()) Commented Nov 30, 2019 at 11:15
  • i use your code . but has error Commented Nov 30, 2019 at 11:23
  • That's only meant as a tip that there's an easier way for .find()+.indexOf() and not an answer ;) Commented Nov 30, 2019 at 11:25
  • Can you add a minimal reproducible example (as snippet) that shows the actual problem. Commented Nov 30, 2019 at 11:26

4 Answers 4

18

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.

Sign up to request clarification or add additional context in comments.

1 Comment

Not Angular @Inputs, Angular data from HttpClient. If you have an array of objects the answer above will not help, you should deep clone the array with all the objects. For example, with JSON.parse(JSON.stringify(this.usersInput))
6

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!

Comments

3

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

Article: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Non_configurable_array_element

Comments

2

Try:

deleteUser(id) {
    const index = this.users.findIndex(x => x.userId === id);
    this.users.splice(index, 1);
}

Working Demo

2 Comments

What should this change on the behavior? OPs script tries to remove "property '1'" hence .find()+.indexOf() have found an element at index 1. This won't change with .findIndex()
@kianoushdortaj I have modified the demo, can you check and let me know your error

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.