Creating a dynamic Array of strings with Add and Remove functionality using AngularJS

I am in need of creating a data binding to an array of strings, specifically an array of directions.

This is how I implemented it:

JS

function ShoppingCartCtrl($scope) {
    $scope.directions = ["a", "b", "c"];
    $scope.addItem = function (item) {
        $scope.directions.push(item);
        $scope.item = "";
    };
    $scope.removeItem = function (index) {
        $scope.directions.splice(index, 1);
    };
}

HTML

<div ng-app>
    <div ng-controller="ShoppingCartCtrl">
        <br />
        <table border="1">
            <thead>
                <tr>
                    <td>directions</td>
                    <td>Remove Item</td>
                </tr>
            </thead>
            <tbody>
                <tr ng-repeat="item in directions">
                    <td>
                        <input ng-model="item" />{{$index}}
                    </td>
                    <td>
                        <input type="button" value="Remove" ng-click="removeItem($index)" />
                    </td>
                </tr>
            </tbody>
        </table>
        <br />
        <table>
            <tr>
                <td>
                    <input type="text" ng-model="item" />
                </td>
                <td colspan="2">
                    <input type="Button" value="Add" ng-click="addItem(item)" />
                </td>
            </tr>
            <tr>
                <td>{{directions}}</td>
            </tr>
        </table>
    </div>
</div>

Although everything seems to be working as expected, there is a bug that I cannot seem to locate. When trying to modify the values directly from the input fields, nothing happens (THIS WAS SOLVED BY USING THE LATEST VERSION OF ANGULAR IN JSFIDDLE).

Continuation: Now you can modify the values, but they are not updated in the model. Any assistance would be greatly appreciated!!

You can view it in action on this jsfiddle

Answer №1

Solution #1: Use object property binding instead of string manipulation

Instead of directly editing the item, it is recommended to update an attribute of the item.

To see a practical example, check out this link: http://jsfiddle.net/ray3whm2/15/

If you seek further information, refer to this article:

Essentially, always bind a property using dot notation, such as item.name instead of just item. This method is mandated by javascript itself and not angularjs.

Solution #2: Manually update your model if necessary

In cases where manual updates are required, you can synchronize your array through the ng-change directive. To see how this works, follow this demonstration: http://jsfiddle.net/ray3whm2/16/

Answer №2

Older versions of Angular had a problem with binding to primitives, which caused issues. For more information, refer to this SO question

The first step is to update Angular to a newer version.

ng-repeat creates a child scope. When using a primitive like a string as the item in ng-repeat="item in directions", modifying <input ng-model="item"> affects the child scope instead of the parent. To resolve this, consider using an array of objects instead:

$scope.directions = [{d: "a"}, {d: "b"}, {d: "c"}];

Then, use

<input ng-model="item.d" />
.

(Alternatively, you can try using ng-model=directions[$index], but it might lose focus after each keypress.

UPDATE: @PSL suggested that adding track by $index could make this approach work)

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 push a variable after employing the split function in JavaScript?

error: An unexpected TypeError occurred while trying to read property 'push'. The error was on this line: " this.name[i].push(arrayData[0]); " I'm confused because the console.log statement before that line shows "data is loaded:" alo ...

What is the method for passing the Rating field value in Vue.js?

Here is the structure of my form: <form id="enquiryBox" method="POST" onSubmit="return false;" data-parsley-validate="true" v-on:submit="handelSubmit($event);"> <div class="modal-body brbottom-20"> <div class="clearfix"> < ...

Safari re-downloads background image when revisiting with jQuery CSS

Using jQuery to set a background-image on my website: $('.header-image').css('background-image', 'url(/img/image.jpg)'); However, upon returning to the page from Safari, the image is downloaded again, unlike Chrome and F ...

Error: "the cart variable in the ctx object has not been defined"

A project I'm currently working on involves a pizza ordering app, and my current focus is on implementing the Cart feature. Each user has their own cart, which includes specific details outlined in cart.ts import { CartItem } from './cartitem&a ...

Issue with InversifyJS @multiInject: receiving an error stating "ServiceIdentifier has an ambiguous match"

Having an issue with inversifyJs while trying to implement dependency injection in my TypeScript project. Specifically, when using the @multiInject decorator, I keep receiving the error "Ambiguous match found for serviceIdentifier". I've been referenc ...

Ways to create a minimatch glob that selects every js file except those within a specific folder

I am currently facing a situation where I require a single glob pattern, utilizing minimatch, to match all JavaScript files except those in a specific directory. Unfortunately, the tool I am using does not offer any options such as an ignore glob, so a sin ...

Switch your attention to the following input text using AngularJS

In my controller, I have an object variable called `myObject` with 3 input text fields in the user interface. I am looking for a way to automatically shift the focus to the next input field once the current one reaches its maximum length. var myObject = ...

Is there a way for me to customize the default icon displayed in the "clear" option of the textAngular directive toolbar?

I am curious about the textAngular directive (https://github.com/fraywing/textAngular) and its various presets such as adding links, blockquotes, etc. However, I am specifically interested in how to customize the default icon for clearing formatting on t ...

The issue persists with the $slice function in MongoDb

I am attempting to retrieve records using an aggregate function in MongoDB, but I keep encountering the error message stating that the operator $slice is invalid: db.getCollection('test').aggregate( [ { $match: { 'subjectId': &apos ...

Storing API data in localStorage using VueJS: A step-by-step guide

As I work on practicing building a simple SPA with VueJS, one of my current tasks involves listening to an API and storing certain data in the browser's localStorage. However, my experience with VueJS is still limited, so I'm unsure about how to ...

Uh oh, the module parsing encountered an error: Unexpected token in React

I recently decided to create my own React component as an npm package and found a helpful guide at this link. However, being new to this, I encountered an error when I tried to run npm.start. Upon running the command, I received the following error messag ...

Creating a function that uses setInterval to continuously update the input with a specific value

I am looking to use the setInterval function to continuously update the value of #test1. Additionally, I want the value of #test1 to be cleared and reset to 1 second after the user clicks a button. Example output can be found here: http://jsfiddle.net/eK ...

Recursive array generation

Given an array 'featureList', the goal is to create a new array 'newArray' based on a specific ID. For example, for ID 5, the newArray would be ['MotherBoard','Antenna','Receiver'], where Receiver correspon ...

The Interactive Menu Toggler: A jQuery Solution

$(window).on('resize', function() { if ( $( window ).width() > 768 ) { $('#menu-main-navigation').show(); } }); $('#nav-toggle').on('click', function() { // start of the nav toggle $('#m ...

Having two menus displayed simultaneously on the screen is not feasible

Achieving the Desired Screen Layout To create a screen layout with two menus, one being the burger menu generated using createDrawerNavigator from react-navigation (located in the top left corner) and the other menu as a bottom button created by createBot ...

Troubleshooting: ng-model items not appearing in AngularJS $scope object

Currently, I am facing an issue while attempting to create a table where users can edit each row and save their changes. After pressing save, only some elements in the row are being sent, and I am having trouble with this. Any help or insights on how to re ...

Transforming an AJAX call into a reusable function

My goal is to simplify my ajax calls by creating a function that can be reused. Although I'm unsure if I'm doing it correctly, I would like to attempt this approach. <script> $(document).ready(function(){ var reg_no=$("#reg_no").va ...

Angular.js, require.js, and jQuery Plugin all combined to create a uniquely customized directive

As a newcomer to Angular and Require, I am seeking assistance with the following code snippet. Despite successfully integrating Angular and Require, I am facing an issue where the bootstrap-switch element fails to initialize: define(['myapp.ui/module ...

Updating array content based on property criteria

I've been tackling a project in Angular where I have two arrays set up like this: array1 = [ { Name: "Jack", Id: "1", Location: "UK" }, { Name: "Rose", Id: "2", Location: ...

What is the best way to instruct Maven to package my JavaScript project as a war file from the root directory?

Hey everyone, I'm still searching for a reliable method to package a javascript project. Typically, the default approach is to simply release it to the docroot of your appserver, which I find quite unpleasant. My simple node.js javascript project, w ...