1

I have created an empty array that I use to loop through to dynamically add and remove text-boxes on my form.

mobiles: Array<string> = [];

<ng-container *ngFor="let mobile of mobiles; index as i">
// Code
</ng-container>

Outside the loop, I have a button to add a new text-box.

<button (click)="addElement()">
</button>

And I have a button inside the loop to remove the specific text-box, based on the index.

<button (click)="removeElement(i)">
</button>

The addElement() function simply pushes an empty value to the end of the array.

this.mobiles.push('');

While the removeElement(index) function removes the index from the array.

if (index in this.mobiles) {
    this.mobiles.splice(index, 1);
}

The issue with this code is that since all values on my array are the same (empty), splice() is not removing the element at the specified index but rather the last element in the array. And as such, it's also removing the last text-box instead of the one I click.

I tested pushing non-empty values in my array but the result is still the same. It only works correctly if I push distinct values, for example:

this.mobiles.push(this.mobiles.length);

I do not want to use this method however, since I plan to fill this array with actual phone numbers.

Is there any alternative?

My Angular version is 7.2.15.

Thank you!

Demo: https://stackblitz.com/edit/angular-phgo61

5
  • 1
    Your method seems perfect if you have implemented the function correctly. The splice function will only remove the specified index and I believe the issue is somewhere else. Can you provide a demo with the usecase? Commented Nov 1, 2019 at 14:35
  • Here you go @Arcteezy: stackblitz.com/edit/angular-phgo61. It's working as I mentioned above, the last element is removed instead of the one I click. Commented Nov 1, 2019 at 14:48
  • It is removing the correct position in the array, however as you are not saving the input strings to the collection it seems like you are removing from the bottom but you are not. Commented Nov 1, 2019 at 14:56
  • See here: stackblitz.com/edit/angular-cwqyjf Commented Nov 1, 2019 at 15:02
  • @joelgullander This is only working correctly because you're adding distinct values in the array. And I am actively trying to avoid doing that, as I mentioned above. Commented Nov 1, 2019 at 15:06

1 Answer 1

1

One workaround for that problem is to wrap each value in an object. The value of each item in the ngFor loop will then be the reference of the object. Since these references are all different, the targeted item will be deleted, as intended.

Using this interface:

interface Phone {
  phoneNumber?: string;
}

You can define an array of Phone objects:

mobiles: Array<Phone> = [];

addElement() {
  this.mobiles.push({});
}

removeElement(index) {
  this.mobiles.splice(index, 1);
}

get phoneNumbers() {
  return this.mobiles.map(x => x.phoneNumber);
}

and edit the phoneNumber property in the template:

<button (click)="addElement()">Add phone</button>
<ng-container *ngFor="let mobile of mobiles; index as i;">
  <div>
    <input [(ngModel)]="mobile.phoneNumber" />
    <button (click)="removeElement(i)">Remove element</button>
  </div>
</ng-container>

See this stackblitz for a demo.

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

1 Comment

This is perfect since I can also store country phone codes separately if I want/need to. Excellent answer, thanks a lot!

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.