Removing elements in AngularJS using ngRepeat

Many have questioned how to implement item removal within the ngRepeat directive. Through my research, I discovered that it involves using ngClick to trigger a removal function with the item's $index.

However, I haven't been able to find an example that addresses multiple ngRepeats:

<div ng-controller="MyController">
    <div ng-repeat="email in user.emails">
        {{ email }} <a href>Remove</a>
    </div>

    <div ng-repeat="phone in user.phones">
        {{ phone }} <a href>Remove</a>
    </div>
</div>

To handle this scenario, I would need to create $scope.removePhone and $scope.removeEmail functions that are called using ngClick on the Remove anchor. However, I am seeking a more universal solution, especially since I have numerous pages with multiple ngRepeats.

I am considering writing a directive that can be placed on the Remove anchor and perform the following actions:

  1. Locate the nearest ngRepeat element among parent elements.
  2. Determine the collection being iterated over ('user.emails' or 'user.phones').
  3. Remove the element at the $index from that model.

This is how the updated markup might look:

<div ng-controller="MyController">
    <div ng-repeat="email in user.emails">
        {{ email }} <a href remove-directive="$index">Remove</a>
    </div>

    <div ng-repeat="phone in user.phones">
        {{ phone }} <a href remove-directive="$index">Remove</a>
    </div>
</div>

Is it possible to achieve what I'm looking for, and what approach should I take?

Current workaround

Presently, I am using a makeshift solution to address this issue. While it may not be ideal, it serves its purpose until I discover a better method.

  myAppModule.controller('MyController', function ($scope, $parse, $routeParams, User) {
    $scope.user = User.get({id: $routeParams.id});

    $scope.remove = function ($index, $event) {
      // TODO: Find a way to make a directive that does this. This is ugly. And probably very wrong.
      var repeatExpr = $($event.currentTarget).closest('[ng-repeat]').attr('ng-repeat');
      var modelPath  = $parse(repeatExpr.split('in')[1].replace(/^\s+|\s+$/g, ''));

      $scope.$eval(modelPath).splice($index, 1);
    };
  });

In the DOM:

<div ng-repeat="email in user.email" class="control-group">
  <label class="control-label">
    {{ "Email Address"|_trans }}
  </label>

  <div class="controls">
    <input type="text" ng-model="email.address">

    <span class="help-inline"><a href ng-click="remove($index, $event)">{{ "Delete"|_trans }}</a></span>
  </div>
</div>

Answer №1

One way to simplify your code is by creating a generic remove function that accepts an array and the item to be removed.

<div ng-app="" ng-controller="MyController">
    <div ng-repeat="email in emails">{{ email }} <a ng-click="remove(emails, $index)">Remove</a>
    </div>
    <div ng-repeat="phone in phones">{{ phone }} <a ng-click="remove(phones, $index)">Remove</a>
    </div>
</div>

$scope.remove = function(array, index){
    array.splice(index, 1);
}

Answer №2

Without JavaScript

<div ng-repeat="item in items" ng-init=items=[6,7,8,9,10]>
   <button ng-click="items.splice($index,1)">Delete me</button>      
</div>

Answer №3

<div ng-app="" ng-controller="MyController">
    <div ng-repeat="item in items as data">{{ item }} 
        <a ng-click="data.splice($index,1)">Delete</a>
    </div>
    <div ng-repeat="number in numbers as data">{{ number }} 
        <a ng-click="data.splice($index,1)">Remove</a>
    </div>
</div>

Answer №4

An easy and effective method that is compatible across different browsers involves utilizing the 'remove' utility function provided by the lodash library.

<div ng-repeat="phone in phones">{{ phone }} 
  <a ng-click="removeItem(phones, phone)">Remove</a>
</div>

In your controller, you need to define the following:

// Inject the lodash dependency

// Declare the method within scope
$scope.removeItem = function(list, item){
   // Use lodash.remove() to remove the specified item from the list
   lodash.remove(list,function(someItem) { return item === someItem});
}

If desired, you can also use indexes for removal. For more information, refer to https://lodash.com/docs#remove

Answer №5

In case you have utilized ng-repeat on an object rather than an array, here is what you should do:

<div ng-app="" ng-controller="MyController">
    <div ng-repeat="email in emails">{{ email }} 
      <a ng-click="remove(emails, email)">Remove</a>
    </div>
    <div ng-repeat="phone in phones">{{ phone }} 
      <a ng-click="remove(phones, phone)">Remove</a>
    </div>
</div>

$scope.remove = function(objects, o){
    delete object[o.id];
}

or a more concise version

<div ng-app="" ng-controller="MyController">
    <div ng-repeat="email in emails">{{ email }} 
      <a ng-click="delete emails[email.id]">Remove</a>
    </div>
    <div ng-repeat="phone in phones">{{ phone }} 
      <a ng-click="delete phones[phone.id]">Remove</a>
    </div>
</div>

Assumes that the objects are structured like this

var emails = {  '123' : { id : '123', .... }  };

var phones = {  '123' : { id : '123', .... }  };

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

If the number exceeds 1, then proceed with this action

I currently have a variable called countTicked, which holds an integer representing the number of relatedBoxes present on the page. I am in need of an if statement that will perform certain actions when the value stored in countTicked exceeds 1. if (!$(c ...

I have instructed angular's $stateProvider to include '/#' in my routes

I'm currently using $stateProvider to manage my routes in Angular 1 and I'm puzzled by the fact that all of my routes have a /# prefix before them. This is causing issues when I try to test these routes in Postman as they result in a 404 error. I ...

Exploring TingoDB: Trouble encountered when passing global variable to insert operation

During my testing and benchmarking of several embedded databases using node.js, I have encountered an interesting issue with TingoDB. Does anyone have insight into why the following code snippet works as expected: var test = { hello:'world' }; f ...

React has reached the maximum update depth limit

In my current project, I am developing a react application that involves a user inputting a search term and receiving an array of JSON data from the backend. On the results page, I have been working on implementing faceted search, which includes several fi ...

Even after deleting the circle from the Google Map, the label still persists within the Google Map Javascript API

Even after removing circles on the Google Map, the labels still persist. I use InfoBox to display labels on circles like this: myOptions.content = datadetail[i].Count; var ibLabel = new InfoBox(myOptions); ibLabel.open(map); I am trying to clear the circ ...

Tips for resolving the error "Encountered duplicate registration of views named RNGestureHandlerButton" in ReactNative

Seeking guidance on implementing a Swipe-to-Delete feature in my App, I manually installed the react-native-gesture-handler. This action triggered an error message which persists even after attempting to uninstall the gesture handler. Any suggestions or so ...

Ensure all asynchronous Ajax requests have completed before considering the page fully loaded

Many websites, such as YouTube, load the majority of their content after the DOM is ready using JavaScript. How can I ensure that all of these requests have been completed before injecting my code? window.onload = function() {}; The above code snippet do ...

A guide on utilizing webpack devServer proxy within a create react app

Currently, I am in the process of developing a new application with create-react-app and I am looking to incorporate some proxies into my code. In the past, I utilized webpack's devServer for this purpose. module.exports = { ... devServer: { ...

Exploring the connections among nodes in a Force-Directed Graph using D3.js JavaScript

I am currently working on a complex graph that consists of around 150 nodes using D3 Javascript. The concept behind it is quite intriguing: Each node is interconnected with 100 other nodes. Out of these 100 nodes, 49 are further linked to another set of ...

Is there a simple method to automatically increase the version number of Mongoose documents with each update request?

I'm eager to utilize Mongooses document versioning feature with the "__v" key. Initially, I struggled with incrementing the version value until I learned that adding this.increment() when executing a query is necessary. Is there a method to have this ...

Dynamic Component Interactions in VueJS using Mouse Events

Just starting out with Vue and other frameworks, so my approach may not be very "Vue-like". I am attempting to create a versatile button component that can have different behaviors based on a prop, in order to maintain just one button component. The desir ...

Add the file to the current directory

As a newer Angular developer, I am embarking on the task of creating a web page that enables users to upload files, with the intention of storing them in a specific folder within the working directory. The current location of the upload page component is ...

Is it possible to send the value of "this" as an argument to a different function in JavaScript?

I currently have the following code: $('#slider li').click(function () { var stepClicked = $(this).index(); alert(stepClicked); if (stepClicked != 0) { $('#cs_previous').removeClass('cs_hideMe'); } els ...

Check if the DIV element does not exist in the DOM before using the

I have been working on a large project and what I need is if div 1 does not contain div 2 as a child{ div1.appendChild(div2) } However, I am facing difficulties in solving this issue Here is my code snippet <script> dc = document.createElement( ...

Angular material components such as buttons and tabs can be positioned in the right top corner for a

Is there a better way to position buttons in the right corner of the md-tab directive? I attempted using position:absolute, but it felt somewhat hacky. <div style="position:absolute; top:15px; right:5px; z-index:5000"> <md-button class="md-pri ...

Switch or toggle between colors using CSS and JavaScript

Greetings for taking the time to review this query! I'm currently in the process of designing a login form specifically catered towards students and teachers One key feature I'm incorporating is a switch or toggle button that alternates between ...

What steps can be taken in Javascript to handle a response status code of 500?

I am currently utilizing a login form to generate and send a URL (referred to as the "full url" stored in the script below) that is expected to return a JSON object. If the login details are accurate, the backend will respond with a JSON object containing ...

The Ajax PHP file uploader is experiencing technical difficulties

I am currently working on an ajax image uploader that is supposed to work automatically when a user submits an image. However, I've encountered an issue where the uploader does not function as expected when I try to rename the images for ordering purp ...

How can we display all products from a database on an online shop using Angular and node.js? The controller is not functioning as expected

My backend is built with node, while the frontend uses angular to display products. However, I'm facing an issue where nothing is being displayed. The database setup is Postgres (Sequelize) and everything seems to be working fine. After examining vari ...

Integrate jquery into an expressJs application

Is there a way to include jQuery in the express app.js file? I need to use jQuery within app.js to make modifications to the HTML file. For example: app.js const express = require('express') const app = express() const $ = global.jQuery = re ...