Adding and removing items in a list with AngularJS

(1) I have encountered a problem while trying to add a new user to a list of items (userList). The issue arises when the list is 'selectable', meaning that when a user selects an item from the list, the textboxes in the HTML code get populated with values from the selected item. This allows for editing of individual properties of the item. Below the group of textboxes is the 'add new user' button. However, when the textboxes are already populated with values and a new user is added without clearing them first, duplicate users appear in the list. Even though this allows for editing, it seems that the new and old users are somehow linked, causing changes made to one to reflect on the other. I suspect that the issue lies in the creation of a new user based on the selected record of the old user.

(2) Deleting a user works well, but it only deletes the user from the bottom of the list. I am looking for a way to select any item in the list and delete that specific item. I tried using the following code snippet:

$scope.userList.splice($scope.userList.indexOf(currentUser), 1);

but it did not work as expected.

My JavaScript code:

<script type="text/javascript">
    function UserController($scope) {
        $scope.userList = [
           { Name: "John Doe1", Title: "xxxx", Company: "yyyy", Place: "zzzz" },
           { Name: "John Doe2", Title: "xxxx", Company: "yyyy", Place: "zzzz" },
           { Name: "John Doe3", Title: "xxxx", Company: "yyyy", Place: "zzzz" },
           { Name: "John Doe4", Title: "xxxx", Company: "yyyy", Place: "zzzz" }
        ];


        $scope.selectUser = function (user) {
            $scope.currentUser = user;
        }

        $scope.addNew = function (currentUser) {
            $scope.userList.push(currentUser);
            $scope.currentUser = {}; //clear out Employee object
        }

        $scope.removeItem = function (currentUser) {
           // $scope.userList.pop(currentUser);
            $scope.userList.splice($scope.userList.indexOf(currentUser), 1);
            $scope.currentUser = {}; //clear out Employee object
        }
    }
</script>

My HTML code:

<div class="row">
        <div style="margin-top: 40px"></div>
        <div data-ng-app="" data-ng-controller="UserController">
            <b>Employee List</b><br />
            <br />
            <ul>
                <li data-ng-repeat="user in userList">

                    <a data-ng-click="selectUser(user)">{{user.Name}} | {{user.Title}} | {{user.Company}} | {{user.Place}}. </a>

                </li>
            </ul>
            <hr>
            <div style="margin-top: 40px"></div>
            <b>Selected Employee</b><br />
            <br />
            <div style="border:dotted 1px grey; padding:20px 0 20px 0; width:40%;">
            <div class="row" style="margin-left: 30px">
                <div style="display: inline-block;">
                    Name: 
                </div>
                <div style="display: inline-block; margin-left: 35px;">
                    <input type="text" data-ng-model="currentUser.Name">
                </div>
            </div>
            <div style="margin-top: 20px"></div>
            <div class="row" style="margin-left: 30px">
                <div style="display: inline-block;">
                    Title: 
                </div>
                <div style="display: inline-block; margin-left: 45px;">
                    <input type="text" data-ng-model="currentUser.Title">
                </div>
            </div>
            <div style="margin-top: 20px"></div>
            <div class="row" style="margin-left: 30px">
                <div style="display: inline-block;">
                    Company: 
                </div>
                <div style="display: inline-block; margin-left: 10px;">
                    <input type="text" data-ng-model="currentUser.Company">
                </div>
            </div>
            <div style="margin-top: 20px"></div>
            <div class="row" style="margin-left: 30px">
                <div style="display: inline-block;">
                    Place:
                </div>
                <div style="display: inline-block; margin-left: 35px;">
                    <input type="text" data-ng-model="currentUser.Place">
                </div>
            </div>
            </div>
            <div>
                <div style="margin: 2% 0 0 8%; display:inline-block">
                    <button data-ng-click="addNew(currentUser)" class="btn btn-primary" type="button">Add New Employee</button>
                </div>
                <div style="margin: 2% 0 0 1%; display:inline-block">
                    <button data-ng-click="removeItem(currentUser)" class="btn btn-primary" type="button">Delete Employee</button>
                </div>
            </div>
            <hr>
            <div style="margin-top: 40px"></div>
            <b>Employee Details:</b><br />
            <br />
            {{currentUser.Name}} is a {{currentUser.Title}} at {{currentUser.Company}}. He currently lives in {{currentUser.Place}}. 
        </div>
    </div>

* EDIT * I resolved the delete user issue by updating the removeItem function as follows:

 $scope.removeItem = function (currentUser) {
                if ($scope.userList.indexOf(currentUser) >= 0) {
                    $scope.userList.splice($scope.userList.indexOf(currentUser), 1);
                    $scope.currentUser = {}; //clear out Employee object
                }
            }

Thanks to the suggestion, the add new user issue has also been successfully resolved.

Answer №1

There are a couple of issues here that need to be addressed. Firstly, in the $scope.addNew() function:

$scope.userList.push(currentUser);

The problem with this line is that it pushes a reference to the same object you are currently editing. This results in the users appearing linked because the same object is present twice in the list. To fix this, you should copy the properties of the object onto a new object using angular.extend():

$scope.userList.push(angular.extend({}, currentUser));

Alternatively, you could consider having the "add new" button add a blank user to the list and select it for editing like this:

$scope.addNew = function () {
    $scope.userList.push($scope.currentUser = {});
};

In the $scope.removeItem() function, there is an issue with using the pop() method of the array to remove a specific item. The pop() method actually removes the last item and does not accept any arguments:

$scope.userList.pop(currentUser);

To successfully remove a specific object from the list, you can iterate through the list and use the following code:

var i;
for (i = 0; i < $scope.userList.length; ++i) {
    if ($scope.userList[i] === currentUser) {
        $scope.userList.splice(i, 1);
        break;
    }
}

Another approach is to use the indexOf() method but ensure that the return value is not -1 before calling splice(), or else the last element will be removed from the list.

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 send the input text to the filter component in my React application?

I am currently working on developing an application utilizing the "Rick and Morty API" to display a list of characters with various attributes such as gender, alive status, images, etc. My main goal is to implement a search bar that allows users to search ...

Tips for adding styling to HTML in Vue by entering CSS code into the CodeMirror editor

Is there a way to style HTML by entering CSS code into the Codemirror editor? For instance, if we have the HTML code <head> </head>, how can I apply the CSS code, head{ color : red }, typed in the Codemirror editor to stylize this HTML code? mo ...

Retrieve the downloaded status of a blob within a specific function

I need a way to verify if the blob downloading process is finished when generating an excel file on the NodeJS server side in response to a request from the React frontend side. Is there a method or promise that can help me achieve this? I want to update t ...

Numerous data inputs to manage with just a single submit button in redux-saga

I am facing an issue with handling multiple inputs and saving the data using a single button in my React component. Here is the method I have implemented: handleClick(e) { e.preventDefault(); this.props.newEmail ? this.props.onSaveNewEmail(this.p ...

"Utilize an HTML file open dialog box to gain access to the server's

Is it feasible to implement a file open dialog box that displays files and directories from the server's file system? In my web application, there is a need for users to select a file that resides on the server. Are there any plugins available for th ...

What is the process for passing an error to the next function within a catch block using catch

It's not uncommon for me to come across code snippets like this app.get('/', function (req, res, next) { Promise.resolve().then(function () { throw new Error('BROKEN') }).catch(next) }) I've been trying to wrap my hea ...

Validation of forms using ajax and javascript

I have implemented ajax on my webpage to dynamically change the content of a main div when different fields in the navigation bar are clicked. However, I am encountering a problem with form validation using JavaScript on elements loaded via ajax. For insta ...

Unable to retrieve element using jQuery because it is specified by its href attribute. This pertains to

I'm having trouble accessing the "a" element with its href attribute. Specifically, I want to add a class to any element that has an href value of "#one". Check out this jsFiddle example. Using jQuery: // The tabs functionality is working correctly ...

Error encountered in React due to a syntax issue with parsing JSON from the response received

The structure of my node.js express server is as follows: const express = require('express'); const app = express(); const port = process.env.PORT || 5000; app.listen(port, () => console.log(`Listening on port ${port}`)); app.get('/exp ...

Do you need to redeclare the type when using an interface with useState in React?

Take a look at this snippet: IAppStateProps.ts: import {INoteProps} from "./INoteProps"; export interface IAppStateProps { notesData: INoteProps[]; } and then implement it here: useAppState.ts: import {INoteProps} from "./interfaces/INo ...

Is it necessary to test the $routeProvider when() configuration to ensure the stability of the application during runtime?

$routeProvider.when('/login', { templateUrl: 'app/login.html', controller: 'LoginController as vm' }); After switching vm to another variable like avm, the code passes unit tests successfully but results in a broken v ...

Error encountered: jQuery version 1.8.0 reports a syntax error due to an unrecognized expression containing ">" symbol

After adding jquery to my website, I encountered an issue with the jQuery 1.8.0 error: Error Message: Syntax error, unrecognized expression: &gt; Can someone please assist me with this problem? ...

Comparing .innerHTML with createElement() | Exploring setAttribute() versus the Direct method*

Someone mentioned that this approach was not considered "proper", but I didn't pay much attention to it until I encountered a run-time error in IE9. Now, I need help converting the code to utilize object properties instead. What is the reason behind i ...

Error: [BITFIELD_INVALID_RANGE]: The bitfield flag or number entered is not valid: 3214336

Currently working on a Discord Dashboard project, but encountering an unusual error: Invalid bitfield flag or number 3214336. This issue arises when attempting to retrieve the guilds that a user has MANAGE_GUILDS permission for. Below is the snippet of my ...

Prettier eliminates the need for parentheses in mathematical expressions

When working with mathematical expressions in React and attempting to slice an array based on those expressions, I encountered an issue with the Prettier extension. It automatically removes parentheses from the expressions, resulting in incorrect calculati ...

Is there a way to trigger a function with the onclick event in NextJs?

Working on my NestJS project, I am still a beginner in the field. My current task involves creating a web application that displays a leaflet map with clickable tiles. Each tile should have a button that triggers a specific function when clicked. However, ...

How can we limit the files served from an Express static directory to only .js files?

I'm curious to know if it's doable to exclusively serve one specific type of file (based on its extension) from an Express.js static directory. Imagine having the following Static directory: Static FileOne.js FileTwo.less FileThree. ...

Stop the duplication of downloading JavaScript files

When it comes to my website, I have incorporated sliders that stream videos from Vimeo. Upon running a check on GTMetrix, I noticed an overwhelming number of http requests. Looking at the waterfall, I discovered numerous duplicate downloads of javascript, ...

Having difficulties implementing horizontal scrolling for the Tabs component in Material UI

I can't seem to enable horizontal scrolling for the Tabs in material UI. Here is the version of Material UI I am using: As the number of Tabs increases, they are becoming wider. I tried to set the width, but it ends up affecting the entire Tabs tab ...

Finding the Right Path: Unraveling the Ember Way

Within my application, I have a requirement for the user to refrain from using the browser's back button once they reach the last page. To address this, I have implemented a method to update the existing url with the current page's url, thereby e ...