Skip to content

Instantly share code, notes, and snippets.

@syabro
Created October 31, 2013 11:46
Show Gist options
  • Save syabro/7248364 to your computer and use it in GitHub Desktop.
Save syabro/7248364 to your computer and use it in GitHub Desktop.
Article

This has bitten me twice in the last 3 days so I’m doing a quick post to remind myself. With AngularJS models, you typically have two way bindings between UI elements and your controller’s properties. Directly from the docs (Plunker)

<!doctype html>
<html ng-app>
 <head>
 <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.0.6/angular.min.js"></script>
 <script src="script.js"></script>

</head>
 <body>

<form name="myForm" ng-controller="Ctrl">
 Single word: <input type="text" name="input" ng-model="text"
 ng-pattern="word" required>
 <span class="error" ng-show="myForm.input.$error.required">
 Required!</span>
 <span class="error" ng-show="myForm.input.$error.pattern">
 Single word only!</span>

<tt>text = {{text}}</tt><br/>
 <tt>myForm.input.$valid = {{myForm.input.$valid}}</tt><br/>
 <tt>myForm.input.$error = {{myForm.input.$error}}</tt><br/>
 <tt>myForm.$valid = {{myForm.$valid}}</tt><br/>
 <tt>myForm.$error.required = {{!!myForm.$error.required}}</tt><br/>
 </form>
 </body>
</html>

JavaScript

function Ctrl($scope) {
 $scope.text = 'guest';
 $scope.word = /^\w*$/;
}

This all works great until you get a simple property that’s a ‘primitive’ so numbers, boolean etc. and you need to use this property within an angular repeater or another directive which creates its own scope. The problem is that, because JavaScript is a pass by value language, primitive types are copied within nested scopes. This means that, if a property changes within a local scope, the original/parent version of the property isn’t updated with those changes. Not only that, angular (for good reason) no longer allow duplicates within a repeater, which is what lead me to StackOverflow the first time I encountered this.

The solution is simply replace the primitive with a JavaScript hash/object so instead of doing something like this:

function Ctrl($scope) {
$scope.myProperty =true;
}

You should do

function Ctrl($scope) {
$scope.myProperty ={someName:true};
}

I highly recommend watching this talk by Miško Hevery on AngularJS best practices. I’ve watched it…not I just need to remember all of it :D

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment