0

Using Angular 4.0.2, I have an *ngFor creating input elements and updating an object array through an add button, but I'm trying to figure out how to update the objects' indeces once an item is removed from that array.

Currently, my ngFor looks like:

*ngFor = let name of names; let i = index

Then, my delete button has a (click) event:

(click)="removeRow(i, names)"

And the method looks like:

    removeRow(index:number, names:Names[]){
        names.splice(index,1);
        index--;
    }

But, when I go to update another input element in the array after removing an object, the indeces are incorrect. It appears that "let i = index" in the *ngFor does not decrement, and I apparently cannot just use:

(click)="removeRow(i, names); i--"
1
  • 3
    You don't need to decrement the index yourself, if you remove an item from the collection ngFor will display the updated items with a new index. Why do you send 'names' as a parameter to the remove function, you already have it in the class ? Commented Jun 21, 2017 at 14:32

3 Answers 3

3

You do not need to manually modify the index set by *ngFor. Angular takes care of it with its two-way data binding. When you modify your "names" array in your component, the view will update itself to reflect the changes, this includes the index on your *ngFor.

*ngFor:

*ngFor="let name of names; let i = index"

Click event:

(click)="removeRow(i)"

Component method:

removeRow(index:number){
    this.names.splice(index,1);
}

Notice that you do not need to pass your array from your view to your component since you already have it in the component.

Edit: Plunker

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

3 Comments

I've tried this, and while the indeces of the names object is updated, the indeces used in the ngFor are not. Basically, if I have two items in an object array, and remove at index 0, and then update the remaining object through an 'update(i)' method, it tries to update at index = 1, instead of it now being at index = 0, thus returning an undefined error.
It is working fine for me when I test it locally, plnkr is down atm so I cannot provide one until it is back up.
Added a plunker link to the answer
1

Without seeing more of your code ... this is only a guess. But I assume you also have a names property of the component class?

Try not passing the names array into the method and instead just removing the element from the bound names property. Angular`s data binding should then take care of the rest.

Template:

<tr *ngFor='let product of products; let i = index'>
    <td>
        <img    [src]='product.imageUrl'
                [title]='product.productName | uppercase'
                (click)="removeRow(i)">
    </td>
</tr>

I had an image so used the click on that ... but it will work the same on a button.

Component class:

removeRow(index: number): void {
    this.products.splice(index,1);
}

Also, I displayed the value of "i" in the template using {{i}} and after deleting a row the "i" value is correctly adjusted for the new set of indices.

5 Comments

Is your suggestion the same as snaplemouton's above? If so, this unfortunately did not do the trick for me.
Can you put together a plunker demonstrating the issue?
Will do- thanks! Looks like plunker is down at the moment, but will check later.
OK, I just added this code to one of my sample projects and it worked just fine as I had described above. I'll update my answer with the key parts of the code.
And yea, when I replied I did not see that there was already a response with this same answer...
0

Isn't i being passed by value into your remove row function? If so you'd have to decrement it in the same scope it exists (Within the ngFor loop).

Example: https://snook.ca/archives/javascript/javascript_pass

Comments

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.