Angular eats my default form values

Today, AngularJS isn't doing what I expect. I've auto-generating a really long form in Django, and adding ng-model attributes so I can summarise the form. Unfortunately, Angular is overwriting my defaults. Here's a shortened example:

<html>
    <head>
    </head>
    <body>
        <form ng-app="testApp" ng-controller="TestCtrl">
            <select name="colour" ng-model="colour">
                <option value="red">Red</option>
                <option value="green" selected="selected">Green</option>
                <option value="blue">Blue</option>
            </select>
            <p>You favourite colour is <span style="color: {{ colour }}">{{ colour }}</span>.</p>
        </form>
        <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.7/angular.min.js"></script>
        <script>
         angular.module('testApp', [])
                .controller('TestCtrl', function($scope) {
                    $scope.$watch('colour', function(newValue) {
                        console.log('Colour is: ' + newValue );
                    });
                });
        </script>
    </body>
</html>

It looks something like this:

After marvelling at how little code you need to do something useful, I note that although the HTML form has Green "selected", the select box is initially has no value selected. Why is that? The reason is that once Angular has loaded, it sets the <select> field to its own initial value of undefined, overwriting the HTML default value.

Enter: Angular Auto Value

Thankfully, John Wright and Glauco Custódio have both come up with libraries to make Angular do what we expect. These are Angular Auto Value and Angular Initial Value respectively. Here's our code after modification to use Angular Auto Value (extra <script> element and 'auto-value' argument to angular.module):

<html>
    <head>
    </head>
    <body>
        <form ng-app="testApp" ng-controller="TestCtrl">
            <select name="colour" ng-model="colour">
                <option value="red">Red</option>
                <option value="green" selected="selected">Green</option>
                <option value="blue">Blue</option>
            </select>
            <p>You favourite colour is <span style="color: {{ colour }}">{{ colour }}</span>.</p>
        </form>
        <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.7/angular.min.js"></script>
        <!-- Extra script -->
        <script src="https://cdn.jsdelivr.net/angular.auto-value/latest/angular-auto-value.min.js"></script>
        <script>
         angular.module('testApp', ['auto-value']) // Extra 'auto-value' dependency
                .controller('TestCtrl', function($scope) {
                    $scope.$watch('colour', function(newValue) {
                        console.log('Colour is: ' + newValue );
                    });
                });
        </script>
    </body>
</html>

I often reach for a pinch of Angular as a "jQuery substitute". A touch of auto-completion or form validation adds a lot of value to a server-side web app. Like jQuery, there's no assumption that your whole system is written in JavaScript. Unlike jQuery, it remains maintainable as you add more and more features.

blogroll

social

Powered by Pelican and Python. Theme by Smashing Magazine.