Using _.without to pass objects and arrays from ng-repeat to a function

My goal is to create reusable functions for adding and removing items from arrays, particularly for editable tables. To achieve this, I pass an object and array to a function using lodash's _.without method. This way, when a row needs to be removed from a table (or any array), I simply pass the object to remove and the corresponding array.

The Problem

When I define the array within the function, everything works as expected - the object is removed, and the DOM is updated accordingly. However, when passing the array as a parameter, the object is removed but the DOM does not update.

Potential Explanation

I suspect that Angular might be unbinding the array passed as a parameter.


Any suggestions on how to maintain the binding of the array parameter?

Take a look at the JSFiddle here

Below is the code snippet:

HTML

<table ng-controller="Ctrl">
  <thead>
    <tr>
      <th>
        <input ng-model="newItem" type="number">
      </th>
      <th>
        <button type="button" ng-click="addItemDef(newItem)">Add - Array Defined</button>
      </th>
      <th>
        <button type="button" ng-click="addItemUndef(newItem, items)">Add - Array Undefined</button>
      </th>
    </tr>
  </thead>
  <tbody>
    <tr ng-repeat="item in items">
      <td>{{item.value}}</td>
      <td>
        <button type="button" ng-click="removeItemDef(item)">Remove - Array Defined</button>
      </td>
      <td>
        <button type="button" ng-click="removeItemUndef(item, items)">Remove - Array Undefined</button>
      </td>
    </tr>
  </tbody>
</table>

Javascript

function Ctrl($scope) {
  $scope.items = [{
    value: 5
  }];

  $scope.addItemDef = function(item) {
    foo = {
        value: item
      }
    $scope.items.push(foo);
  };
  $scope.addItemUndef = function(item, array) {
    thing = {
      value: item
    }
    array.push(thing);
  };

  $scope.removeItemDef = function(obj) {
    $scope.items = _.without($scope.items, obj);
  };

  $scope.removeItemUndef = function(obj, array) {
    array = _.without(array, obj);
  };
};

Answer №1

When you call lodash's _.without, a new array is created.

After that, you replace the parameter reference inside the function scope with the newly created copy from _.without, which does not affect the original argument passed in.

// The following code won't work:
$scope.removeItemUndef = function(obj, array) {
   console.log('Before', array, $scope.items);
   array = _.without(array, obj); // << overwriting reference with no effect
   console.log('After', array, $scope.items);
};

To successfully modify the contents of the array passed as an argument without altering its reference, you should use Array.splice.

// However, this solution will work:
$scope.removeItemUndef = function(obj, array) {
   console.log('Before', array, $scope.items);
   var result = _.without(array, obj);
   // Replace current content with result's content using Array.prototype.splice.apply:
   Array.prototype.splice.apply(array, [0, array.length].concat(result));
   console.log('After', array, $scope.items);
};

Check out the updated jsfiddle for a demonstration.

The reason for using

Array.prototyp.splice.apply(array, ...)
instead of array.splice(...) is because splice accepts spread arguments rather than an array. Using the .apply method allows you to pass an array as arguments.

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

A new module is unable to load Angular Material

Recently, I developed an Angular material module similar to a core module. import { NgModule} from '@angular import {MatCheckboxModule} from '@angular/material/checkbox'; @NgModule({ imports: [ MatCheckboxModule ], exports: [ ...

What is the best way to modify an attribute in an SVG file using JavaScript?

I am struggling to find a solution that works for my specific situation. I am trying to display an svg file on an html page and manipulate its code elements using javascript. My goal is to change the attributes of certain elements, specifically by adding ...

jQuery - selecting child elements with a strict hierachy restrictions

Can you provide the equivalent jQuery selector if I have a variable $table that references $('table.special') to start with? (something like $table.(...) but matching the original selector $('table.special > thead > tr')) Note: ...

Is there a method available for troubleshooting unsuccessful AJAX requests? Why might my request be failing?

Whenever I click on a button with the class "member-update-button," an alert pops up saying "got an error, bro." The error callback function is being triggered. Any thoughts on why this might be happening? No errors are showing up in the console. How can I ...

Eratosthenes' Filtering Method in Rust

Currently, I am working on implementing a sieve of Eratosthenes in Rust. I plan to use this code multiple times, so I am in the process of creating a function to execute the sieve. However, I have encountered an obstacle. I prefer using an array over a vec ...

Is it advisable to utilize $timeout in AngularJS for executing a function after ng-repeat has completed?

Currently, I am utilizing the ngRepeat directive to display a large data list. In order to execute a function after the completion of the ng-repeat, I have incorporated the use of the $timeout. While this approach is functioning effectively, my concern is ...

Tweet button script fails to work properly when inserted via ajax loading

The following code snippet is used for Twitter integration: <script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src="https://platform.twitter.com/widgets.js";fjs.parentNode.in ...

I attempted to post a collection of strings in ReactJS, only to receive a single string response from the Web

I was troubleshooting an issue where only one string from ReactJS was being sent to WebApi instead of an array of strings. Below is the ReactJS code snippet I used: import React, { useState } from "react"; import axios from "axios"; e ...

Verifying the user's email and password for authentication

Is there a way to verify the authenticity of the email and password entered in the form, so that I can redirect to a new page? Unfortunately, upon reloading the page, the validation process seems to fail in checking whether the user email and password are ...

Processing the file to convert it into an array of integers

Currently, I am tackling HEVC specifically X265, and my focus is on inputting the QP array with values read from a file. It's important to note that these values range from 0 to 100. To test this process, I have set up a test file where I've inc ...

Issue arises when trying to set object members using a callback function in Typescript

I am facing a peculiar issue that I have yet to unravel. My goal is to display a textbox component in Angular 2, where you can input a message, specify a button label, and define a callback function that will be triggered upon button click. Below is the c ...

Is there a way to retrieve data from local storage after every login in Laravel?

Utilizing Laravel 5.3, I have been storing my data on local storage using JavaScript: localStorage.setItem('storedData', JSON.stringify(data)) Now, when a user logs in, I want to implement a condition. If the stored data exists in the local sto ...

Issues in retrieving meaningful output from an external function

My goal is to render a div component with a dynamic class. In order to later evaluate it in the object's state, I am setting the div's class to match the "piece" state. To update the state, I have created an external JS function that returns a ra ...

Designing the tomahawk file upload component

Attempting to customize the t:inputFileUpload element, a solution was tried from styling an input type=file. This involves adding another input element and image to occupy the same space as the t:inputFileUpload. Below is the code snippet: <div id="fil ...

Error message encountered: "The requested resource does not exist, the name has been modified, or it is currently unavailable on the Azure Web Application where the Angular application is hosted."

After successfully publishing my Angular app to Azure Web Apps and testing it locally, I encountered an unexpected error (HTTP Error 404.0 - Not Found) related to the D:\home\site\wwwroot\bin\www file: https://i.sstatic.net/tztKO. ...

Retrieving a numerical value from a constantly changing string

The string is constantly changing. For example: Date15:Month8:Year1990 Is there a way to extract the number 15 without using substring, since the values are always different? I am looking to extract only the number after "Date" and before ":". ...

Struggling with creating and exporting TailwindCSS and NextJS

I'm encountering challenges in constructing and exporting my TailwindCSS and NextJS project. While everything works smoothly when running `npm run dev` with all Tailwind classes functioning properly, I face an issue when executing `npm run build && np ...

Eliminating the initial array to streamline the JSON output

I have a simple function that generates an array which can be easily "json_encoded." This function works well. However, I now need to repeat this process multiple times. while($row = mysql_fetch_assoc($resultsol)) { $all[] = jsonoutput("$row[appid]"); ...

Request with content Type multipart/form experienced Error 406

I encountered an issue with my axios request in Express const formData = new FormData(); formData.append("file", fs.createReadStream(file.path)); formData.append("requestid", '123456'); const options = { method: 'POST& ...

Rotating an arrow image on an accordion using jQuery

I have been working on this page located at Unfortunately, my attempts to showcase the issue in a jsfiddle were unsuccessful. The webpage features an accordion-style FAQ section, and I am attempting to make the arrow rotate 90 degrees when a question is ...