AngularJS: Did you know…? From 1.0 to 1.3, part 1

Szymon Kosno
5 min readOct 25, 2015

--

Few days ago we all had opportunity to learn a lot of new things about Angular 1 and 2 with Angular Connect 2015 (if you haven’t checked it, I urge you to view recordings here). There are many new features that soon (hopefully)will be available for developers. In the meantime it is good to look back at what we might have missed in a stack we are currently using.

This time I will focus on features made available around version 1.0 — 1.3 (part 1 and part 2). I will follow up in another post focusing on changes introduced somewhere between 1.3–1.4.

DISCLAIMER! This is not a change log or tutorial — it is just a list of features that might have been overlooked when working with Angular.

What features were introduced?

  1. You can use ternary operator for assignments in expressions
scope.$eval(‘a = 1 ? 2 : 3’);
expect(scope.a).toBe(2);
scope.$eval(‘0 ? a = 2 : a = 3’);
expect(scope.a).toBe(3);
scope.$eval(‘1 ? a = 2 : a = 3’);
expect(scope.a).toBe(2);

2. There is „$submitted, $touched, $untouched” parameter available in form controller as well as “$setSubmitted(), $setUntouched()” and on ngModel “$setTouched()”

3. Default directive restriction is now „EA” instead of „A”

4. $q can be used in streamlined version

$q(function(resolve, reject) { resolve(data); })

5. You can make multiline directives (like ng-repeat-start and -end) but there is a special property “multiElement: true”

6. You can escape interpolation with “\\”

\\{\\{foo\\}\\}

7. ngRepeat can alias result if there is a filter applied on array repeated so that the result set can be referred in the loop

8. You can bind ng-model to getter/setter function

9. You can force all pending model updates to be immediately executed

When working with forms you can happen to click “submit” button before models are really updated (because of things like debounce option or similar). In such case there is a form method $commitViewValue that will immediately commit all pending updates to model

IMPORTANT: when you handle form submit through “ng-submit” action, this is done automatically. In case of “ng-click” it has to be done manually.

10. There is “strict-di” mode available that will make sure code is ready for production builds (uglify etc.)

angular.bootstrap(document, [“name”], {
strictDi: true
});
OR<html ng-app=”name” ng-strict-di>
<!-- … -->
</html>

11. You can modify ng-model behaviour by passing to ng-model-options configuration object

  • updateOn: string specifying which event should the input be bound to. You can set several events using an space delimited list. There is a special event called default that matches the default events belonging of the control, e.g. ng-model-options=“{ updateOn: ‘default blur’ }
  • debounce: integer value which contains the debounce model update value in milliseconds. A value of 0 triggers an immediate update. If an object is supplied instead, you can specify a custom value for each event. For example: ng-model-options=“{ debounce: { ‘default’: 500, ‘blur’: 0 } }”
  • allowInvalid: boolean value which indicates that the model can be set with values that did not validate correctly instead of the default behavior of setting the model to undefined.
  • getterSetter: boolean value which determines whether or not to treat functions bound to ngModel as getters/setters.

12. $observe now returns de-registration function like $watch

13. You can register controllers, services and filters by passing map instead of standard (‘name’, function) pair (can be useful with require etc.)

.controller({
name1: function1,
name2: function2});

14. Forms support expressions as form names. This means you can bind form to controller instance

<form name=”ctrl.form”>
...
function YourController () {
this.form; //form is available on "this" in controller
}

15. You can disable debug mode (no classes like ng-scope) for production app (aprox. 10% faster)

myApp.config([‘$compileProvider’, function ($compileProvider) {
$compileProvider.debugInfoEnabled(false);
}]);

But you can always reload application again in debug mode (e.g. on production incident debug)

angular.reloadWithDebugInfo();

16. You can (and should) bind isolated scope attributes directly into controller instance instead of scope when using “controllerAs” syntax

scope: {
'myData': '=someData',
'myString': '@someInterpolation',
'myExpr': '&someExpr'
},
controllerAs: “someCtrl”,
bindtoController: true

17. You can coalesce calls to $apply for $http responses which occur close together (so that only one $digest is there)

angular.module(‘myFancyApp’, []).
config(['$httpProvider', function($httpProvider) {
$httpProvider.useApplyAsync(true);
});
OR:angular.mock.module(function($httpProvider) {
$httpProvider.useApplyAsync(true);
});

18. You can coalesce in fact any call to $apply by using $applyAsync instead

NOTE: Within the $digest, $applyAsync() will only flush if the current scope is the $rootScope. This means that if you call $digest on a child scope, it will not implicitly flush the $applyAsync() queue. http://www.bennadel.com/blog/2751-scope-applyasync-vs-scope-evalasync-in-angularjs-1-3.htm

19. You can request download of template (and storying it in $templateCache) using new $templateRequest service

20. Date filter can be passed third parameter “UTC” to parse date against UTC instead of browser time zone

21. input ngModelOptions accepts timezone setting

timezone: Defines the timezone to be used to read/write the Date instance in the model for <input type=”date”>, <input type=”time”>, … . It understands UTC/GMT and the continental US time zone abbreviations

22. “filter” filter is now passing index to function predicate (so you can make filtering function based on index)

23. You can use interpolated values in “name” attribute on form elements

<input type=”text” ng-model=”name” name=”name{{nameID}}” />

24. You can specify what type of document is template loaded by directive by specifying “templateNamespace” to one of “html, svg, math”

25. You can target “only parent” elements when requiring directive controllers

require: '^^ngModel'
require: '?^^ngModel'

See you next time — end of part 1

That’s all for today, hope you have found something interesting in this list. As always I urge you to read full AngularJS change log to always be up-to-date:

This post is now continued with “AngularJS: Did you know…? From 1.0 to 1.3, part 2”:

--

--

Szymon Kosno

Technical Program Manager at Google, Developer most of the time unless trying to meditate