1

I am trying to provide default values for some model properties, and am trying to accomplish this using $watches. I can't use the ordinary 2 way binding as I need the model properties to initially be empty. However, while my $watches are setting the properties ok, the HTML that is bound to them isn't getting updated.

<!doctype html>
<body ng-app="TestApp" ng-controller="TestCtrl">
    <div><input ng-model="form.firstname" placeholder="enter your first name"/></div>
    <div><input ng-model="form.lastname" placeholder="enter your last name"/></div>    
    <p>{{user.firstname}}</p>
    <p>{{user.lastname}}</p>
</body>

angular.module('TestApp', [])
.controller('TestCtrl', ['$scope', function($scope) {

    $scope.user = new User({
        firstname: 'Bruce',
        lastname: 'Wayne'
    });

    function User(defaults) {
        angular.extend(this, defaults);
        $scope.form = {};

        angular.forEach(this, function(value, key) {
            $scope.form[key] = '';

            $scope.$watch(function() {
                return $scope.form[key];
            }, function (val) {
                this[key] = val || defaults[key];
                console.log(val)
                console.log(defaults[key])
                console.log(this[key])
            });
        });
    }
}]);

See a fiddle here - what I want is for any value entered in the box to be reflected in the text, and then if the value is deleted, for the default text to show up again. If you check the console, you'll see that the watch callback is working properly. I did try to wrap the update in $apply but got $digest in progress error.

Fairly new to angular, so am probably going the wrong way about trying to accomplish this!

1 Answer 1

1

The problem is that this changes while the $watcher runs.

    function User(defaults) {
        angular.extend(this, defaults);
        $scope.form = {};

        var self = this; // <-- Saving `this`.

        angular.forEach(this, function(value, key) {
            $scope.form[key] = '';

            $scope.$watch(function() {
                return $scope.form[key];
            }, function (val) {
                self[key] = val || defaults[key];
                console.log(val)
                console.log(defaults[key])
                console.log(self[key])
            });
        });

Saving this solves the problem: http://jsfiddle.net/637yypz1/1/

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.