Why is my AngularJs 'add' button only working once?


I’m just starting out with Angular.

I’ve written some code that downloads a JSON array configuredAPIs and displays each object within it, <div ng-repeat="capi in configuredAPIs">. For each of these, there’s another directive to list the items from an array of strings, <tr ng-repeat="eurl in capi.externalURLs">

Underneath there’s a text box to add a new string to this array, which I’ve bound to a $scope variable called url.

When I click the ‘add’ button, everything works – the new string is added to the array, a new row appears in the table.. ..but it only works once. Subsequent clicks on the ‘add’ button add empty strings to the array (and thus empty text boxes).

What have I done wrong?


    <div ng-app="testApp" ng-controller="testCtrl">

        <div ng-repeat="capi in configuredAPIs">

            <h1>Configured API</h1>
                {{ capi.name }}

            <h2>External URLs</h2>
            <form ng-submit="addExternalURL(capi)">
                    <!-- A row in the table for each string in the array -->
                    <tr ng-repeat="eurl in capi.externalURLs">
                            <input type="text" ng-model="eurl" />

                    <!-- Final table row to add a new string to the array -->
                            <input type="text" ng-model="url" placeholder="Enter a new external URL">
                            <input class="btn-primary" type="submit" value="add">



var app = angular.module('testApp', []);
app.controller('testCtrl', function ($scope, $http) {

    $scope.url = 'new url';

    .success(function (response) { $scope.configuredAPIs = response; });

    $scope.addExternalURL = function ($capi) {
        $scope.url = '';



It is because AngularJS does not watch and update primitives (e.g. strings, numbers, booleans) the way one obviously thinks it does.

So instead you bind objects with values to the scope or use a function which returns the primitive value.




Example for using an object (at controller):

$scope.primitives = {
    url : 'foo://'

And within the template:

<input type="text" ng-model="primitives.url">

So what happens in your example is that once you set it to '' the changes to the model within the template are not recognized anymore.

Answered By – conceptdeluxe

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply

(*) Required, Your email will not be published