Transferring elements between arrays using AngularJS

As a seasoned C#/ASP.NET developer, my company is transitioning to AngularJS for all future front-end web development projects.

I have encountered a specific challenge that I'm trying to solve. I have a SELECT element bound to an array of "email" objects with properties like "id" and "name". Instead of using ng-repeat, I am utilizing ng-options for data binding. My goal is to select an item from the list, click a button, and then remove it from the original list while adding it to a secondary list. Initially, I considered checkboxes but due to the large number of items in the array, my project manager preferred a different approach.

In order to achieve this functionality, I referred to various JavaScript array functions available at: http://www.w3schools.com/jsref/jsref_obj_array.asp

Coming from a C# background, I am finding it challenging to identify the right technique in JavaScript to accomplish this task efficiently. How can I locate the item in the source array, remove it, and insert it into the target array while maintaining alphabetical sorting based on the "name" property?

This leads me to another question regarding the efficiency of my SELECT binding. Currently, when I select an item and click the button, the ng-model attribute is linked to the "id" of the item which requires scanning the array associated with the SELECT element to retrieve the selected item. Is there a way in AngularJS to bind directly to the object itself instead of its "id" so that I can access the selected item without having to scan through the array? Here is the code snippet where I am binding to the "id":

JS:

$scope.addEmailToGroup = function(emailID) {
  var email = getEmailByID($scope.emails, emailID);

  if (email !== null) {
    // TODO: Move item from one array to the other
  }
};

function getEmailByID(arr, id) {
  var email = null;
  var length = arr.length;

  for (var i = 0; i < length; i++) {
    if (arr[i].id === id) {
      email = angular.copy(arr[i]);
      break;
    }
  }

  return email;
}

HTML:

<select id="emails" class="form-control" data-ng-model="selectedEmailID" name="emails" data-ng-options="email.id as email.name  for email in emails"></select>
<button class="btn btn-default" data-ng-click="addEmailToGroup(selectedEmailID)" type="button">
  <span class="glyphicon glyphicon-plus"></span>
</button>

Answer №1

Assuming your email IDs are in numeric form, you have the option to utilize them as array indexes and access them simply like this:

$scope.emails[emailID];

If that seems too cumbersome, another approach is to use a dictionary array to map $scope.emails IDs to their respective array keys.


Let's delve into using a dictionary method. Now, you no longer need to loop through all objects in the emails array. Instead, you can employ indexOf on the dictionary variable to retrieve the complete email object. In your application, you only need to iterate through the emails once to construct the dictionary.

var emails = [ // placeholder emails object
  {id: 3,  email: '<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="7003181f1d0a301508111d001c155e131f1d">[email protected]</a>'},
  {id: 5,  email: '<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="60240513051214260f18213a200518010d100c054e030f0d">[email protected]</a>'},
  {id: 12, email: '<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="5d0e32303832333818312e381d38253c302d3138733e3230">[email protected]</a>'}
];

var dict = []; // initialize the dictionary here

for(var i = 0; i < emails.length; i++){ // create the dictionary
  dict.push(emails[i].id);
}

function getEmailById(id){
  return emails[dict.indexOf(parseInt(id, 10))];
}


document.getElementById('b').addEventListener('click', function(){
  var id = document.getElementById('n').value;
  document.getElementById('res').textContent = 
    JSON.stringify(getEmailById(id)) || "Not found";
});
<input type="number" id="n" placeholder="Enter email ID">
<button id="b">Get Email</button>
<p id="res">Enter email ID in the box above, then click the button</p>

Answer №2

I've devised a unique solution that combines the best of both worlds. By binding my SELECT directly to the object, I eliminated the need to search through the array.

<select id="emails" class="form-control" data-ng-model="selectedEmail" name="emails" data-ng-options="email.name for email in emails track by email.id">
</select>
<button class="btn btn-default" data-ng-click="addEmailToGroup()" type="button">
    <span class="glyphicon glyphicon-plus"></span>
</button>

For transferring an item from one array to another, I implemented this code:

$scope.addEmailToGroup = function () {
    if ($scope.selectedEmail) {
        var pos = -1;
        var length = $scope.emails.length;

        for (var i = 0; i < length; i++) {
            if ($scope.emails[i].id === $scope.selectedEmail.id) {
                pos = i;
                break;
            }
        }

        $scope.emails.splice(pos, 1);
        $scope.selectedEmails.push($scope.selectedEmail);
    }
};

Although @Shomz and @charlietfl offered alternative solutions, I believe that this method suits my requirements perfectly.

Thank you for your valuable input.

Apologies for the snippet above not functioning correctly. It was my first time posting on StackOverflow...

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

What is the best way to refresh my view after loading a new JavaScript file that is required to generate the correct HTML elements?

When I use $http.get() to retrieve my model $scope.workoutData, the object appears fine in the console.log(data) output. However, my view does not load as if it has received the model. Once the model is updated, I also need to trigger the owlCarousel() fun ...

Eliminate repeated entries in a drop-down menu and display them with commas in between

I am working with a list that contains various language combinations: German to English German to Spanish German to Chinese German to French English to Spanish English to French English to Greek English to Portuguese Does anyone have suggestions on how ...

Developing NodeJS applications locally using Docker

How can I effectively develop an app locally within a container with access to my laptop's file system for the node_modules? Currently, my Dockerfile includes the following settings: COPY package.json /app/ RUN npm install COPY . /app/ And my docke ...

Javascript has trouble processing data coming from an HTML input field

I am struggling to make my JavaScript code work with the input from my HTML input tag. The purpose of this program is for the user to input a number, and then the program will determine whether the number is positive, negative, or zero. Below is the code ...

Issue encountered during compilation in webpack when using the require() method with an imagePath

I'm currently attempting to dynamically load an image within a ReactJS project. Unfortunately, the solutions I've come across online have not been successful for me. Here is a snippet of my react component: class ReadOnlyTableRow extends React. ...

How can I retrieve the checked values of checkboxes and store them in an array using React?

https://i.sstatic.net/jTRRU.png This toggle button is dynamically generated based on data, and I need to save the checked values in an array. Code {this.state.customersmsselect.map((e, key) => { if(e.isactive == "ON"){ return ( &l ...

Utilizing the power of JavaScript, CSS, and HTML to seamlessly transfer selected items from one webpage to the shopping cart displayed on another page

Due to limitations on using back-end code, I'm seeking advice on how to implement this function. Most tutorials I've come across show the items and shopping cart on the same page. I've heard suggestions about using Jquery.load(), but I&apos ...

Switch on the warning signal using bootstrap

How can I make the alert below toggle after 2 seconds? <div class="alert alert-info"> <a href="#" class="close" data-dismiss="alert">&times;</a> Data was saved. </div> ...

Is there a difference in performance when adding objects to $scope.array compared to using var x = [ ] in AngularJS?

When it comes to tasks like this, I find myself needing to handle situations like the following: $scope.my_array = []; var obj; for (var i = 0; i < data.length; i++) { obj = {}; obj.item1 = data.something; obj.item2 = data.somethingElse; ...

Tips for temporarily preventing a digest cycle when modifying a scope variable

Is there a way to edit an array of objects in AngularJS, linked to the view through ng-repeat, without updating the scope until all objects have been modified? Consider this scenario: I need to update each object in the array and only then reflect the ch ...

Learn how to implement form validation on a sliding form in just 5 easy steps using jQuery

I am new to programming and I struggle to comprehend complex JavaScript code written by others. Instead of using intricate code that I don't understand, I would like to request help in creating a simplified jQuery script for me to implement. Current ...

Employing a combination of IF clauses for form validation

While implementing form validation, I encountered an issue where only the length check was being performed and not the empty string check. This led to only one error message being displayed instead of two separate messages for each scenario. How can I modi ...

What is the process for extracting the value of a checkbox generated through JavaScript?

I recently came across a helpful post on Stack Overflow that provided sample code demonstrating how to display multiple list of checkboxes dynamically on a dropdown list. The function in the code was exactly what I needed for my webpage. However, I encount ...

When Vue is clicked, it appears to trigger multiple methods simultaneously

Currently, I am learning Vue and encountered a problem that I need help with. When using the v-on:click directive to call a method, all other instance methods are also called when the same method is used elsewhere. HTML: <div id="exercise"> &l ...

Add a new element to an array of sub-documents. Surprising results observed

I have been attempting to add a new field to each sub-document within all arrays of sub-documents. My script is partially working, but instead of inserting the ordinal_number into every sub-document, it seems to only be adding it to the first sub-document ...

Mapping JSON data from an array with multiple properties

Here is a JSON object that I have: obj = { "api": "1.0.0", "info": { "title": "Events", "version": "v1", "description": "Set of events" }, "topics": { "cust.created.v1": { "subscribe": { ...

What are the drawbacks of making API calls in getStaticProps?

After looking through the nextJs documentation, I came across a recommendation not to make API calls within the getStaticProps function. Can someone provide a clear example explaining why this is advised? The reason given in the docs is that server-side ...

Ways to display JSX with formatted new lines and spaces in React.js?

Here is an image displaying a comparison between my console log and React website in Google Chrome. Check out the Console log and Chrome website Notice how the console output is neatly formatted with new lines and indents, while the text below "Generated ...

What is the reason that self focus doesn't function in JavaScript?

Whenever an input element triggers a blur event, I want to focus on a specific element. The issue arises when I try to focus on the same element that caused the blur event. Why does this only work when the element I am focusing on is not the one triggeri ...

What is the best way to update the content within a Div element?

I'm currently working on a project in AngularJS where the data in the backend is updated every 30 seconds. I need to ensure that these changes are reflected on the front end. Is there a way to automatically refresh the div every 10 seconds to achieve ...