Angular Tips and Tricks

Angular Tips and Tricks

Most of JS developers have seen at least several times the AngularJs into presentations. So most of the people are pretty familiar with AngularJs at this post. This will be two parts presentation. First part will be deep dive into Angular’s injector object, explaining how dependency injection is working. In the second part, I’ll share tips and tricks I learn by working with AngularJs for more than an year.

Code samples can be found at:
https://github.com/RStankov/talk-angular-tips-tricks

7a0e72a6f55811246bb5d9a946fd2e49?s=128

Radoslav Stankov

August 27, 2014
Tweet

Transcript

  1. 3.
  2. 5.
  3. 6.
  4. 7.
  5. 9.
  6. 29.
  7. 41.
  8. 54.

    app.factory('Person', function($window) { var name = ''; ! return {

    setName: function(newName) { name = newName; }, getName: function() { return name; }, say: function(text) { $window.alert(name + ' - ' + text); } } });
  9. 55.

    app.factory('Person', function($window) { var name = ''; ! return {

    setName: function(newName) { name = newName; }, getName: function() { return name; }, say: function(text) { $window.alert(name + ' - ' + text); } } });
  10. 56.

    app.factory('Person', function($window) { var name = ''; ! return {

    setName: function(newName) { name = newName; }, getName: function() { return name; }, say: function(text) { $window.alert(name + ' - ' + text); } } });
  11. 57.

    app.factory('Person', function($window) { var name = ''; ! return {

    setName: function(newName) { name = newName; }, getName: function() { return name; }, say: function(text) { $window.alert(name + ' - ' + text); } } });
  12. 58.

    app.factory('Person', function($window) { var name = ''; ! return {

    setName: function(newName) { name = newName; }, getName: function() { return name; }, say: function(text) { $window.alert(name + ' - ' + text); } } });
  13. 59.

    app.factory('Person', function($window) { var name = ''; ! return {

    setName: function(newName) { name = newName; }, getName: function() { return name; }, say: function(text) { $window.alert(name + ' - ' + text); } } });
  14. 60.

    app.factory('Person', function($window) { var name = ''; ! return {

    setName: function(newName) { name = newName; }, getName: function() { return name; }, say: function(text) { $window.alert(name + ' - ' + text); } } });
  15. 61.

    app.factory('Person', function($window) { var name = ''; ! return {

    setName: function(newName) { name = newName; }, getName: function() { return name; }, say: function(text) { $window.alert(name + ' - ' + text); } } });
  16. 62.

    app.factory('Person', function($window) { var name = ''; ! return {

    setName: function(newName) { name = newName; }, getName: function() { return name; }, say: function(text) { $window.alert(name + ' - ' + text); } } });
  17. 63.

    app.factory('Person', function($window) { var name = ''; ! return {

    setName: function(newName) { name = newName; }, getName: function() { return name; }, say: function(text) { $window.alert(name + ' - ' + text); } } });
  18. 64.

    app.factory('Person', function($window) { var name = ''; ! return {

    setName: function(newName) { name = newName; }, getName: function() { return name; }, say: function(text) { $window.alert(name + ' - ' + text); } } });
  19. 65.

    app.factory('Person', function($window) { var name = ''; ! return {

    setName: function(newName) { name = newName; }, getName: function() { return name; }, say: function(text) { $window.alert(name + ' - ' + text); } } });
  20. 66.

    app.factory('Person', function($window) { var name = ''; ! return {

    setName: function(newName) { name = newName; }, getName: function() { return name; }, say: function(text) { $window.alert(name + ' - ' + text); } } });
  21. 73.

    app.service('Person', function($window) { var name = ''; ! this.setName =

    function(newName) { name = newName; }; ! this.getName = function() { return name; }; ! this.say = function(text) { $window.alert(name + ' - ' + text); }; });
  22. 74.

    app.service('Person', function($window) { var name = ''; ! this.setName =

    function(newName) { name = newName; }; ! this.getName = function() { return name; }; ! this.say = function(text) { $window.alert(name + ' - ' + text); }; });
  23. 75.

    app.service('Person', function($window) { var name = ''; ! this.setName =

    function(newName) { name = newName; }; ! this.getName = function() { return name; }; ! this.say = function(text) { $window.alert(name + ' - ' + text); }; });
  24. 76.

    app.service('Person', function($window) { var name = ''; ! this.setName =

    function(newName) { name = newName; }; ! this.getName = function() { return name; }; ! this.say = function(text) { $window.alert(name + ' - ' + text); }; });
  25. 77.

    app.service('Person', function($window) { var name = ''; ! this.setName =

    function(newName) { name = newName; }; ! this.getName = function() { return name; }; ! this.say = function(text) { $window.alert(name + ' - ' + text); }; });
  26. 80.

    app.provider('Person', function() { this.name = ''; ! this.$get = function($window)

    { var self = this; return { setName: function(newName) { self.name = newName; }, getName: function() { return self.name; }, say: function(text) { $window.alert(self.name + ' - ' + text); } }; } });
  27. 81.

    app.provider('Person', function() { this.name = ''; ! this.$get = function($window)

    { var self = this; return { setName: function(newName) { self.name = newName; }, getName: function() { return self.name; }, say: function(text) { $window.alert(self.name + ' - ' + text); } }; } });
  28. 82.

    app.provider('Person', function() { this.name = ''; ! this.$get = function($window)

    { var self = this; return { setName: function(newName) { self.name = newName; }, getName: function() { return self.name; }, say: function(text) { $window.alert(self.name + ' - ' + text); } }; } });
  29. 83.

    app.provider('Person', function() { this.name = ''; ! this.$get = function($window)

    { var self = this; return { setName: function(newName) { self.name = newName; }, getName: function() { return self.name; }, say: function(text) { $window.alert(self.name + ' - ' + text); } }; } });
  30. 84.

    app.provider('Person', function() { this.name = ''; ! this.$get = function($window)

    { var self = this; return { setName: function(newName) { self.name = newName; }, getName: function() { return self.name; }, say: function(text) { $window.alert(self.name + ' - ' + text); } }; } });
  31. 85.

    app.provider('Person', function() { this.name = ''; ! this.$get = function($window)

    { var self = this; return { setName: function(newName) { self.name = newName; }, getName: function() { return self.name; }, say: function(text) { $window.alert(self.name + ' - ' + text); } }; } });
  32. 86.

    app.provider('Person', function() { this.name = ''; ! this.$get = function($window)

    { var self = this; return { setName: function(newName) { self.name = newName; }, getName: function() { return self.name; }, say: function(text) { $window.alert(self.name + ' - ' + text); } }; } });
  33. 87.

    app.provider('Person', function() { this.name = ''; ! this.$get = function($window)

    { var self = this; return { setName: function(newName) { self.name = newName; }, getName: function() { return self.name; }, say: function(text) { $window.alert(self.name + ' - ' + text); } }; } });
  34. 88.

    app.provider('Person', function() { this.name = ''; ! this.$get = function($window)

    { var self = this; return { setName: function(newName) { self.name = newName; }, getName: function() { return self.name; }, say: function(text) { $window.alert(self.name + ' - ' + text); } }; } });
  35. 89.

    app.provider('Person', function() { this.name = ''; ! this.$get = function($window)

    { var self = this; return { setName: function(newName) { self.name = newName; }, getName: function() { return self.name; }, say: function(text) { $window.alert(self.name + ' - ' + text); } }; } });
  36. 103.
  37. 104.
  38. 121.
  39. 122.

    https://github.com/angular/angular.js/blob/master/src/auto/injector.js function provider(name, provider_) { assertNotHasOwnProperty(name, 'service'); ! if (isFunction(provider_)

    || isArray(provider_)) { provider_ = providerInjector.instantiate(provider_); } ! if (!provider_.$get) { throw $injectorMinErr('pget', "Provider '{0}' must define $get fac } ! return providerCache[name + providerSuffix] = provider_; }
  40. 123.

    https://github.com/angular/angular.js/blob/master/src/auto/injector.js function provider(name, provider_) { assertNotHasOwnProperty(name, 'service'); ! if (isFunction(provider_)

    || isArray(provider_)) { provider_ = providerInjector.instantiate(provider_); } ! if (!provider_.$get) { throw $injectorMinErr('pget', "Provider '{0}' must define $get fac } ! return providerCache[name + providerSuffix] = provider_; }
  41. 124.

    https://github.com/angular/angular.js/blob/master/src/auto/injector.js function provider(name, provider_) { assertNotHasOwnProperty(name, 'service'); ! if (isFunction(provider_)

    || isArray(provider_)) { provider_ = providerInjector.instantiate(provider_); } ! if (!provider_.$get) { throw $injectorMinErr('pget', "Provider '{0}' must define $get fac } ! return providerCache[name + providerSuffix] = provider_; }
  42. 125.

    https://github.com/angular/angular.js/blob/master/src/auto/injector.js function provider(name, provider_) { assertNotHasOwnProperty(name, 'service'); ! if (isFunction(provider_)

    || isArray(provider_)) { provider_ = providerInjector.instantiate(provider_); } ! if (!provider_.$get) { throw $injectorMinErr('pget', "Provider '{0}' must define $get fac } ! return providerCache[name + providerSuffix] = provider_; }
  43. 126.

    https://github.com/angular/angular.js/blob/master/src/auto/injector.js function provider(name, provider_) { assertNotHasOwnProperty(name, 'service'); ! if (isFunction(provider_)

    || isArray(provider_)) { provider_ = providerInjector.instantiate(provider_); } ! if (!provider_.$get) { throw $injectorMinErr('pget', "Provider '{0}' must define $get fac } ! return providerCache[name + providerSuffix] = provider_; }
  44. 127.

    https://github.com/angular/angular.js/blob/master/src/auto/injector.js function provider(name, provider_) { assertNotHasOwnProperty(name, 'service'); ! if (isFunction(provider_)

    || isArray(provider_)) { provider_ = providerInjector.instantiate(provider_); } ! if (!provider_.$get) { throw $injectorMinErr('pget', "Provider '{0}' must define $get fac } ! return providerCache[name + providerSuffix] = provider_; }
  45. 128.

    https://github.com/angular/angular.js/blob/master/src/auto/injector.js function provider(name, provider_) { assertNotHasOwnProperty(name, 'service'); ! if (isFunction(provider_)

    || isArray(provider_)) { provider_ = providerInjector.instantiate(provider_); } ! if (!provider_.$get) { throw $injectorMinErr('pget', "Provider '{0}' must define $get fac } ! return providerCache[name + providerSuffix] = provider_; }
  46. 129.

    https://github.com/angular/angular.js/blob/master/src/auto/injector.js function provider(name, provider_) { assertNotHasOwnProperty(name, 'service'); ! if (isFunction(provider_)

    || isArray(provider_)) { provider_ = providerInjector.instantiate(provider_); } ! if (!provider_.$get) { throw $injectorMinErr('pget', "Provider '{0}' must define $get fac } ! return providerCache[name + providerSuffix] = provider_; }
  47. 130.

    https://github.com/angular/angular.js/blob/master/src/auto/injector.js function provider(name, provider_) { assertNotHasOwnProperty(name, 'service'); ! if (isFunction(provider_)

    || isArray(provider_)) { provider_ = providerInjector.instantiate(provider_); } ! if (!provider_.$get) { throw $injectorMinErr('pget', "Provider '{0}' must define $get fac } ! return providerCache[name + providerSuffix] = provider_; }
  48. 131.

    https://github.com/angular/angular.js/blob/master/src/auto/injector.js function provider(name, provider_) { assertNotHasOwnProperty(name, 'service'); ! if (isFunction(provider_)

    || isArray(provider_)) { provider_ = providerInjector.instantiate(provider_); } ! if (!provider_.$get) { throw $injectorMinErr('pget', "Provider '{0}' must define $get fac } ! return providerCache[name + providerSuffix] = provider_; }
  49. 132.

    https://github.com/angular/angular.js/blob/master/src/auto/injector.js function provider(name, provider_) { assertNotHasOwnProperty(name, 'service'); ! if (isFunction(provider_)

    || isArray(provider_)) { provider_ = providerInjector.instantiate(provider_); } ! if (!provider_.$get) { throw $injectorMinErr('pget', "Provider '{0}' must define $get fac } ! return providerCache[name + providerSuffix] = provider_; }
  50. 133.

    https://github.com/angular/angular.js/blob/master/src/auto/injector.js function provider(name, provider_) { assertNotHasOwnProperty(name, 'service'); ! if (isFunction(provider_)

    || isArray(provider_)) { provider_ = providerInjector.instantiate(provider_); } ! if (!provider_.$get) { throw $injectorMinErr('pget', "Provider '{0}' must define $get fac } ! return providerCache[name + providerSuffix] = provider_; }
  51. 134.

    https://github.com/angular/angular.js/blob/master/src/auto/injector.js function provider(name, provider_) { assertNotHasOwnProperty(name, 'service'); ! if (isFunction(provider_)

    || isArray(provider_)) { provider_ = providerInjector.instantiate(provider_); } ! if (!provider_.$get) { throw $injectorMinErr('pget', "Provider '{0}' must define $get fac } ! return providerCache[name + providerSuffix] = provider_; }
  52. 142.

    https://github.com/angular/angular.js/blob/master/src/auto/injector.js function provider(name, provider_) { assertNotHasOwnProperty(name, 'service'); ! if (isFunction(provider_)

    || isArray(provider_)) { provider_ = providerInjector.instantiate(provider_); } ! if (!provider_.$get) { throw $injectorMinErr('pget', "Provider '{0}' must define $get fac } ! return providerCache[name + providerSuffix] = provider_; }
  53. 143.

    https://github.com/angular/angular.js/blob/master/src/auto/injector.js function provider(name, provider_) { assertNotHasOwnProperty(name, 'service'); ! if (isFunction(provider_)

    || isArray(provider_)) { provider_ = providerInjector.instantiate(provider_); } ! if (!provider_.$get) { throw $injectorMinErr('pget', "Provider '{0}' must define $get fac } ! return providerCache[name + providerSuffix] = provider_; }
  54. 144.

    https://github.com/angular/angular.js/blob/master/src/auto/injector.js function provider(name, provider_) { assertNotHasOwnProperty(name, 'service'); ! if (isFunction(provider_)

    || isArray(provider_)) { provider_ = providerInjector.instantiate(provider_); } ! if (!provider_.$get) { throw $injectorMinErr('pget', "Provider '{0}' must define $get fac } ! return providerCache[name + providerSuffix] = provider_; }
  55. 145.

    function instantiate(Type, locals, serviceName) { var Constructor = function() {};

    Constructor.prototype = (isArray(Type) ? Type[Type.length - 1] : Typ var instance = new Constructor(); var returnedValue = invoke(Type, instance, locals, serviceName); ! if (isObject(returnedValue) || isFunction(returnedValue)) { return returnedValue; } else { return instance; } } https://github.com/angular/angular.js/blob/master/src/auto/injector.js
  56. 146.

    function instantiate(Type, locals, serviceName) { var Constructor = function() {};

    Constructor.prototype = (isArray(Type) ? Type[Type.length - 1] : Typ var instance = new Constructor(); var returnedValue = invoke(Type, instance, locals, serviceName); ! if (isObject(returnedValue) || isFunction(returnedValue)) { return returnedValue; } else { return instance; } } https://github.com/angular/angular.js/blob/master/src/auto/injector.js
  57. 147.

    function instantiate(Type, locals, serviceName) { var Constructor = function() {};

    Constructor.prototype = (isArray(Type) ? Type[Type.length - 1] : Typ var instance = new Constructor(); var returnedValue = invoke(Type, instance, locals, serviceName); ! if (isObject(returnedValue) || isFunction(returnedValue)) { return returnedValue; } else { return instance; } } https://github.com/angular/angular.js/blob/master/src/auto/injector.js
  58. 148.

    function instantiate(Type, locals, serviceName) { var Constructor = function() {};

    Constructor.prototype = (isArray(Type) ? Type[Type.length - 1] : Typ var instance = new Constructor(); var returnedValue = invoke(Type, instance, locals, serviceName); ! if (isObject(returnedValue) || isFunction(returnedValue)) { return returnedValue; } else { return instance; } } https://github.com/angular/angular.js/blob/master/src/auto/injector.js
  59. 149.

    function instantiate(Type, locals, serviceName) { var Constructor = function() {};

    Constructor.prototype = (isArray(Type) ? Type[Type.length - 1] : Typ var instance = new Constructor(); var returnedValue = invoke(Type, instance, locals, serviceName); ! if (isObject(returnedValue) || isFunction(returnedValue)) { return returnedValue; } else { return instance; } } https://github.com/angular/angular.js/blob/master/src/auto/injector.js
  60. 150.

    function instantiate(Type, locals, serviceName) { var Constructor = function() {};

    Constructor.prototype = (isArray(Type) ? Type[Type.length - 1] : Typ var instance = new Constructor(); var returnedValue = invoke(Type, instance, locals, serviceName); ! if (isObject(returnedValue) || isFunction(returnedValue)) { return returnedValue; } else { return instance; } } https://github.com/angular/angular.js/blob/master/src/auto/injector.js
  61. 151.

    function instantiate(Type, locals, serviceName) { var Constructor = function() {};

    Constructor.prototype = (isArray(Type) ? Type[Type.length - 1] : Typ var instance = new Constructor(); var returnedValue = invoke(Type, instance, locals, serviceName); ! if (isObject(returnedValue) || isFunction(returnedValue)) { return returnedValue; } else { return instance; } } https://github.com/angular/angular.js/blob/master/src/auto/injector.js
  62. 152.

    https://github.com/angular/angular.js/blob/master/src/auto/injector.js* function invoke(fn, self, locals, serviceName) { var args =

    [], $inject = annotate(fn, strictDi, serviceName); ! for(var i = 0, length = $inject.length; i < length; i++) { var key = $inject[i]; if (typeof key !== 'string') { throw $injectorMinErr('...'); } args.push(getService(key)); } ! return fn.apply(self, args); }
  63. 153.

    https://github.com/angular/angular.js/blob/master/src/auto/injector.js* function invoke(fn, self, locals, serviceName) { var args =

    [], $inject = annotate(fn, strictDi, serviceName); ! for(var i = 0, length = $inject.length; i < length; i++) { var key = $inject[i]; if (typeof key !== 'string') { throw $injectorMinErr('...'); } args.push(getService(key)); } ! return fn.apply(self, args); }
  64. 154.

    https://github.com/angular/angular.js/blob/master/src/auto/injector.js* function invoke(fn, self, locals, serviceName) { var args =

    [], $inject = annotate(fn, strictDi, serviceName); ! for(var i = 0, length = $inject.length; i < length; i++) { var key = $inject[i]; if (typeof key !== 'string') { throw $injectorMinErr('...'); } args.push(getService(key)); } ! return fn.apply(self, args); }
  65. 155.

    https://github.com/angular/angular.js/blob/master/src/auto/injector.js* function invoke(fn, self, locals, serviceName) { var args =

    [], $inject = annotate(fn, strictDi, serviceName); ! for(var i = 0, length = $inject.length; i < length; i++) { var key = $inject[i]; if (typeof key !== 'string') { throw $injectorMinErr('...'); } args.push(getService(key)); } ! return fn.apply(self, args); }
  66. 156.

    https://github.com/angular/angular.js/blob/master/src/auto/injector.js* function invoke(fn, self, locals, serviceName) { var args =

    [], $inject = annotate(fn, strictDi, serviceName); ! for(var i = 0, length = $inject.length; i < length; i++) { var key = $inject[i]; if (typeof key !== 'string') { throw $injectorMinErr('...'); } args.push(getService(key)); } ! return fn.apply(self, args); }
  67. 157.

    https://github.com/angular/angular.js/blob/master/src/auto/injector.js* function invoke(fn, self, locals, serviceName) { var args =

    [], $inject = annotate(fn, strictDi, serviceName); ! for(var i = 0, length = $inject.length; i < length; i++) { var key = $inject[i]; if (typeof key !== 'string') { throw $injectorMinErr('...'); } args.push(getService(key)); } ! return fn.apply(self, args); }
  68. 160.

    function MyFactory(Dependancy1, Dependancy2) { /* code */ } ! MyFactory.$inject

    = ['Dependancy1', 'Dependancy2'] ! app.factory('MyFactory', MyFactory);
  69. 161.

    https://github.com/angular/angular.js/blob/master/src/auto/injector.js* function invoke(fn, self, locals, serviceName) { var args =

    [], $inject = annotate(fn, strictDi, serviceName); ! for(var i = 0, length = $inject.length; i < length; i++) { var key = $inject[i]; if (typeof key !== 'string') { throw $injectorMinErr('...'); } args.push(getService(key)); } ! return fn.apply(self, args); }
  70. 162.

    https://github.com/angular/angular.js/blob/master/src/auto/injector.js* function invoke(fn, self, locals, serviceName) { var args =

    [], $inject = annotate(fn, strictDi, serviceName); ! for(var i = 0, length = $inject.length; i < length; i++) { var key = $inject[i]; if (typeof key !== 'string') { throw $injectorMinErr('...'); } args.push(getService(key)); } ! return fn.apply(self, args); }
  71. 163.

    https://github.com/angular/angular.js/blob/master/src/auto/injector.js* function invoke(fn, self, locals, serviceName) { var args =

    [], $inject = annotate(fn, strictDi, serviceName); ! for(var i = 0, length = $inject.length; i < length; i++) { var key = $inject[i]; if (typeof key !== 'string') { throw $injectorMinErr('...'); } args.push(getService(key)); } ! return fn.apply(self, args); }
  72. 164.

    https://github.com/angular/angular.js/blob/master/src/auto/injector.js* function invoke(fn, self, locals, serviceName) { var args =

    [], $inject = annotate(fn, strictDi, serviceName); ! for(var i = 0, length = $inject.length; i < length; i++) { var key = $inject[i]; if (typeof key !== 'string') { throw $injectorMinErr('...'); } args.push(getService(key)); } ! return fn.apply(self, args); }
  73. 165.

    https://github.com/angular/angular.js/blob/master/src/auto/injector.js* function invoke(fn, self, locals, serviceName) { var args =

    [], $inject = annotate(fn, strictDi, serviceName); ! for(var i = 0, length = $inject.length; i < length; i++) { var key = $inject[i]; if (typeof key !== 'string') { throw $injectorMinErr('...'); } args.push(getService(key)); } ! return fn.apply(self, args); }
  74. 166.

    https://github.com/angular/angular.js/blob/master/src/auto/injector.js* function invoke(fn, self, locals, serviceName) { var args =

    [], $inject = annotate(fn, strictDi, serviceName); ! for(var i = 0, length = $inject.length; i < length; i++) { var key = $inject[i]; if (typeof key !== 'string') { throw $injectorMinErr('...'); } args.push(getService(key)); } ! return fn.apply(self, args); }
  75. 167.

    https://github.com/angular/angular.js/blob/master/src/auto/injector.js* function invoke(fn, self, locals, serviceName) { var args =

    [], $inject = annotate(fn, strictDi, serviceName); ! for(var i = 0, length = $inject.length; i < length; i++) { var key = $inject[i]; if (typeof key !== 'string') { throw $injectorMinErr('...'); } args.push(getService(key)); } ! return fn.apply(self, args); }
  76. 168.

    https://github.com/angular/angular.js/blob/master/src/auto/injector.js* function invoke(fn, self, locals, serviceName) { var args =

    [], $inject = annotate(fn, strictDi, serviceName); ! for(var i = 0, length = $inject.length; i < length; i++) { var key = $inject[i]; if (typeof key !== 'string') { throw $injectorMinErr('...'); } args.push(getService(key)); } ! return fn.apply(self, args); }
  77. 169.

    https://github.com/angular/angular.js/blob/master/src/auto/injector.js* function invoke(fn, self, locals, serviceName) { var args =

    [], $inject = annotate(fn, strictDi, serviceName); ! for(var i = 0, length = $inject.length; i < length; i++) { var key = $inject[i]; if (typeof key !== 'string') { throw $injectorMinErr('...'); } args.push(getService(key)); } ! return fn.apply(self, args); }
  78. 170.

    function annotate(fn, strictDi, name) { var $inject; ! if (typeof

    fn === 'function') { if (!($inject = fn.$inject)) { // ... fill inject from argument names } } else if (isArray(fn)) { var last = fn.length - 1; assertArgFn(fn[last], 'fn'); $inject = fn.slice(0, last); } else { assertArgFn(fn, 'fn', true); } return $inject; } https://github.com/angular/angular.js/blob/master/src/auto/injector.js*
  79. 171.

    function annotate(fn, strictDi, name) { var $inject; ! if (typeof

    fn === 'function') { if (!($inject = fn.$inject)) { // ... fill inject from argument names } } else if (isArray(fn)) { var last = fn.length - 1; assertArgFn(fn[last], 'fn'); $inject = fn.slice(0, last); } else { assertArgFn(fn, 'fn', true); } return $inject; } https://github.com/angular/angular.js/blob/master/src/auto/injector.js*
  80. 172.

    function annotate(fn, strictDi, name) { var $inject; ! if (typeof

    fn === 'function') { if (!($inject = fn.$inject)) { // ... fill inject from argument names } } else if (isArray(fn)) { var last = fn.length - 1; assertArgFn(fn[last], 'fn'); $inject = fn.slice(0, last); } else { assertArgFn(fn, 'fn', true); } return $inject; } https://github.com/angular/angular.js/blob/master/src/auto/injector.js*
  81. 173.

    function annotate(fn, strictDi, name) { var $inject; ! if (typeof

    fn === 'function') { if (!($inject = fn.$inject)) { // ... fill inject from argument names } } else if (isArray(fn)) { var last = fn.length - 1; assertArgFn(fn[last], 'fn'); $inject = fn.slice(0, last); } else { assertArgFn(fn, 'fn', true); } return $inject; } https://github.com/angular/angular.js/blob/master/src/auto/injector.js*
  82. 174.

    function annotate(fn, strictDi, name) { var $inject; ! if (typeof

    fn === 'function') { if (!($inject = fn.$inject)) { // ... fill inject from argument names } } else if (isArray(fn)) { var last = fn.length - 1; assertArgFn(fn[last], 'fn'); $inject = fn.slice(0, last); } else { assertArgFn(fn, 'fn', true); } return $inject; } https://github.com/angular/angular.js/blob/master/src/auto/injector.js*
  83. 175.

    function annotate(fn, strictDi, name) { var $inject; ! if (typeof

    fn === 'function') { if (!($inject = fn.$inject)) { // ... fill inject from argument names } } else if (isArray(fn)) { var last = fn.length - 1; assertArgFn(fn[last], 'fn'); $inject = fn.slice(0, last); } else { assertArgFn(fn, 'fn', true); } return $inject; } https://github.com/angular/angular.js/blob/master/src/auto/injector.js*
  84. 176.

    function annotate(fn, strictDi, name) { var $inject; ! if (typeof

    fn === 'function') { if (!($inject = fn.$inject)) { // ... fill inject from argument names } } else if (isArray(fn)) { var last = fn.length - 1; assertArgFn(fn[last], 'fn'); $inject = fn.slice(0, last); } else { assertArgFn(fn, 'fn', true); } return $inject; } https://github.com/angular/angular.js/blob/master/src/auto/injector.js*
  85. 177.

    function annotate(fn, strictDi, name) { var $inject; ! if (typeof

    fn === 'function') { if (!($inject = fn.$inject)) { // ... fill inject from argument names } } else if (isArray(fn)) { var last = fn.length - 1; assertArgFn(fn[last], 'fn'); $inject = fn.slice(0, last); } else { assertArgFn(fn, 'fn', true); } return $inject; } https://github.com/angular/angular.js/blob/master/src/auto/injector.js*
  86. 178.

    function annotate(fn, strictDi, name) { var $inject; ! if (typeof

    fn === 'function') { if (!($inject = fn.$inject)) { // ... fill inject from argument names } } else if (isArray(fn)) { var last = fn.length - 1; assertArgFn(fn[last], 'fn'); $inject = fn.slice(0, last); } else { assertArgFn(fn, 'fn', true); } return $inject; } https://github.com/angular/angular.js/blob/master/src/auto/injector.js*
  87. 179.

    function annotate(fn, strictDi, name) { var $inject; ! if (typeof

    fn === 'function') { if (!($inject = fn.$inject)) { // ... fill inject from argument names } } else if (isArray(fn)) { var last = fn.length - 1; assertArgFn(fn[last], 'fn'); $inject = fn.slice(0, last); } else { assertArgFn(fn, 'fn', true); } return $inject; } https://github.com/angular/angular.js/blob/master/src/auto/injector.js*
  88. 180.

    function annotate(fn, strictDi, name) { var $inject; ! if (typeof

    fn === 'function') { if (!($inject = fn.$inject)) { // ... fill inject from argument names } } else if (isArray(fn)) { var last = fn.length - 1; assertArgFn(fn[last], 'fn'); $inject = fn.slice(0, last); } else { assertArgFn(fn, 'fn', true); } return $inject; } https://github.com/angular/angular.js/blob/master/src/auto/injector.js*
  89. 181.

    function annotate(fn, strictDi, name) { var $inject; ! if (typeof

    fn === 'function') { if (!($inject = fn.$inject)) { // ... fill inject from argument names } } else if (isArray(fn)) { var last = fn.length - 1; assertArgFn(fn[last], 'fn'); $inject = fn.slice(0, last); } else { assertArgFn(fn, 'fn', true); } return $inject; } https://github.com/angular/angular.js/blob/master/src/auto/injector.js*
  90. 182.

    function annotate(fn, strictDi, name) { var $inject; ! if (typeof

    fn === 'function') { if (!($inject = fn.$inject)) { // ... fill inject from argument names } } else if (isArray(fn)) { var last = fn.length - 1; assertArgFn(fn[last], 'fn'); $inject = fn.slice(0, last); } else { assertArgFn(fn, 'fn', true); } return $inject; } https://github.com/angular/angular.js/blob/master/src/auto/injector.js*
  91. 183.

    https://github.com/angular/angular.js/blob/master/src/auto/injector.js* function invoke(fn, self, locals, serviceName) { var args =

    [], $inject = annotate(fn, strictDi, serviceName); ! for(var i = 0, length = $inject.length; i < length; i++) { var key = $inject[i]; if (typeof key !== 'string') { throw $injectorMinErr('...'); } args.push(getService(key)); } ! return fn.apply(self, args); }
  92. 184.

    https://github.com/angular/angular.js/blob/master/src/auto/injector.js* function invoke(fn, self, locals, serviceName) { var args =

    [], $inject = annotate(fn, strictDi, serviceName); ! for(var i = 0, length = $inject.length; i < length; i++) { var key = $inject[i]; if (typeof key !== 'string') { throw $injectorMinErr('...'); } args.push(getService(key)); } ! return fn.apply(self, args); }
  93. 185.

    https://github.com/angular/angular.js/blob/master/src/auto/injector.js* function invoke(fn, self, locals, serviceName) { var args =

    [], $inject = annotate(fn, strictDi, serviceName); ! for(var i = 0, length = $inject.length; i < length; i++) { var key = $inject[i]; if (typeof key !== 'string') { throw $injectorMinErr('...'); } args.push(getService(key)); } ! return fn.apply(self, args); }
  94. 187.

    https://github.com/angular/angular.js/blob/master/src/auto/injector.js function getService(serviceName) { if (cache.hasOwnProperty(serviceName)) { if (cache[serviceName] ===

    INSTANTIATING) { throw $injectorMinErr('cdep', 'Circular dependency found: {0}', serviceName + ' <- ' + path.join(' <- ')); } return cache[serviceName]; } else { // ... code } }
  95. 188.

    https://github.com/angular/angular.js/blob/master/src/auto/injector.js function getService(serviceName) { if (cache.hasOwnProperty(serviceName)) { if (cache[serviceName] ===

    INSTANTIATING) { throw $injectorMinErr('cdep', 'Circular dependency found: {0}', serviceName + ' <- ' + path.join(' <- ')); } return cache[serviceName]; } else { // ... code } }
  96. 189.

    https://github.com/angular/angular.js/blob/master/src/auto/injector.js function getService(serviceName) { if (cache.hasOwnProperty(serviceName)) { if (cache[serviceName] ===

    INSTANTIATING) { throw $injectorMinErr('cdep', 'Circular dependency found: {0}', serviceName + ' <- ' + path.join(' <- ')); } return cache[serviceName]; } else { // ... code } }
  97. 190.

    https://github.com/angular/angular.js/blob/master/src/auto/injector.js function getService(serviceName) { if (cache.hasOwnProperty(serviceName)) { if (cache[serviceName] ===

    INSTANTIATING) { throw $injectorMinErr('cdep', 'Circular dependency found: {0}', serviceName + ' <- ' + path.join(' <- ')); } return cache[serviceName]; } else { // ... code } }
  98. 191.

    https://github.com/angular/angular.js/blob/master/src/auto/injector.js function getService(serviceName) { if (cache.hasOwnProperty(serviceName)) { if (cache[serviceName] ===

    INSTANTIATING) { throw $injectorMinErr('cdep', 'Circular dependency found: {0}', serviceName + ' <- ' + path.join(' <- ')); } return cache[serviceName]; } else { // ... code } }
  99. 192.

    https://github.com/angular/angular.js/blob/master/src/auto/injector.js function getService(serviceName) { if (cache.hasOwnProperty(serviceName)) { if (cache[serviceName] ===

    INSTANTIATING) { throw $injectorMinErr('cdep', 'Circular dependency found: {0}', serviceName + ' <- ' + path.join(' <- ')); } return cache[serviceName]; } else { // ... code } }
  100. 193.

    https://github.com/angular/angular.js/blob/master/src/auto/injector.js function getService(serviceName) { if (cache.hasOwnProperty(serviceName)) { if (cache[serviceName] ===

    INSTANTIATING) { throw $injectorMinErr('cdep', 'Circular dependency found: {0}', serviceName + ' <- ' + path.join(' <- ')); } return cache[serviceName]; } else { // ... code } }
  101. 194.

    https://github.com/angular/angular.js/blob/master/src/auto/injector.js function getService(serviceName) { if (cache.hasOwnProperty(serviceName)) { // ... code

    } else { try { path.unshift(serviceName); cache[serviceName] = INSTANTIATING; return cache[serviceName] = factory(serviceName); } catch (err) { if (cache[serviceName] === INSTANTIATING) { delete cache[serviceName]; } throw err; } finally { path.shift(); } } }
  102. 195.

    https://github.com/angular/angular.js/blob/master/src/auto/injector.js function getService(serviceName) { if (cache.hasOwnProperty(serviceName)) { // ... code

    } else { try { path.unshift(serviceName); cache[serviceName] = INSTANTIATING; return cache[serviceName] = factory(serviceName); } catch (err) { if (cache[serviceName] === INSTANTIATING) { delete cache[serviceName]; } throw err; } finally { path.shift(); } } }
  103. 196.

    https://github.com/angular/angular.js/blob/master/src/auto/injector.js function getService(serviceName) { if (cache.hasOwnProperty(serviceName)) { // ... code

    } else { try { path.unshift(serviceName); cache[serviceName] = INSTANTIATING; return cache[serviceName] = factory(serviceName); } catch (err) { if (cache[serviceName] === INSTANTIATING) { delete cache[serviceName]; } throw err; } finally { path.shift(); } } }
  104. 197.

    https://github.com/angular/angular.js/blob/master/src/auto/injector.js function getService(serviceName) { if (cache.hasOwnProperty(serviceName)) { // ... code

    } else { try { path.unshift(serviceName); cache[serviceName] = INSTANTIATING; return cache[serviceName] = factory(serviceName); } catch (err) { if (cache[serviceName] === INSTANTIATING) { delete cache[serviceName]; } throw err; } finally { path.shift(); } } }
  105. 198.

    https://github.com/angular/angular.js/blob/master/src/auto/injector.js function getService(serviceName) { if (cache.hasOwnProperty(serviceName)) { // ... code

    } else { try { path.unshift(serviceName); cache[serviceName] = INSTANTIATING; return cache[serviceName] = factory(serviceName); } catch (err) { if (cache[serviceName] === INSTANTIATING) { delete cache[serviceName]; } throw err; } finally { path.shift(); } } }
  106. 199.

    https://github.com/angular/angular.js/blob/master/src/auto/injector.js function getService(serviceName) { if (cache.hasOwnProperty(serviceName)) { // ... code

    } else { try { path.unshift(serviceName); cache[serviceName] = INSTANTIATING; return cache[serviceName] = factory(serviceName); } catch (err) { if (cache[serviceName] === INSTANTIATING) { delete cache[serviceName]; } throw err; } finally { path.shift(); } } }
  107. 200.

    https://github.com/angular/angular.js/blob/master/src/auto/injector.js function getService(serviceName) { if (cache.hasOwnProperty(serviceName)) { // ... code

    } else { try { path.unshift(serviceName); cache[serviceName] = INSTANTIATING; return cache[serviceName] = factory(serviceName); } catch (err) { if (cache[serviceName] === INSTANTIATING) { delete cache[serviceName]; } throw err; } finally { path.shift(); } } }
  108. 202.
  109. 207.
  110. 209.

    https://github.com/angular/angular.js/blob/master/src/Angular.js function bootstrap(element, modules, config) { // ... setup !

    var doBootstrap = function() { // ... do bootstrapping }; ! // ... call doBootstrap }
  111. 210.

    https://github.com/angular/angular.js/blob/master/src/Angular.js var doBootstrap = function() { element = jqLite(element); !

    // ... ! modules.unshift(['$provide', function($provide) { $provide.value('$rootElement', element); }]); modules.unshift('ng'); var injector = createInjector(modules, config.strictDi); injector.invoke(['$rootScope', '$rootElement', '$compile', '$injector function bootstrapApply(scope, element, compile, injector) { scope.$apply(function() { element.data('$injector', injector); compile(element)(scope); }); }] ); return injector; };
  112. 211.

    https://github.com/angular/angular.js/blob/master/src/Angular.js var doBootstrap = function() { element = jqLite(element); !

    // ... ! modules.unshift(['$provide', function($provide) { $provide.value('$rootElement', element); }]); modules.unshift('ng'); var injector = createInjector(modules, config.strictDi); injector.invoke(['$rootScope', '$rootElement', '$compile', '$injector function bootstrapApply(scope, element, compile, injector) { scope.$apply(function() { element.data('$injector', injector); compile(element)(scope); }); }] ); return injector; };
  113. 212.

    https://github.com/angular/angular.js/blob/master/src/Angular.js var doBootstrap = function() { element = jqLite(element); !

    // ... ! modules.unshift(['$provide', function($provide) { $provide.value('$rootElement', element); }]); modules.unshift('ng'); var injector = createInjector(modules, config.strictDi); injector.invoke(['$rootScope', '$rootElement', '$compile', '$injector function bootstrapApply(scope, element, compile, injector) { scope.$apply(function() { element.data('$injector', injector); compile(element)(scope); }); }] ); return injector; };
  114. 213.

    https://github.com/angular/angular.js/blob/master/src/Angular.js var doBootstrap = function() { element = jqLite(element); !

    // ... ! modules.unshift(['$provide', function($provide) { $provide.value('$rootElement', element); }]); modules.unshift('ng'); var injector = createInjector(modules, config.strictDi); injector.invoke(['$rootScope', '$rootElement', '$compile', '$injector function bootstrapApply(scope, element, compile, injector) { scope.$apply(function() { element.data('$injector', injector); compile(element)(scope); }); }] ); return injector; };
  115. 214.

    https://github.com/angular/angular.js/blob/master/src/Angular.js var doBootstrap = function() { element = jqLite(element); !

    // ... ! modules.unshift(['$provide', function($provide) { $provide.value('$rootElement', element); }]); modules.unshift('ng'); var injector = createInjector(modules, config.strictDi); injector.invoke(['$rootScope', '$rootElement', '$compile', '$injector function bootstrapApply(scope, element, compile, injector) { scope.$apply(function() { element.data('$injector', injector); compile(element)(scope); }); }] ); return injector; };
  116. 215.

    https://github.com/angular/angular.js/blob/master/src/Angular.js var doBootstrap = function() { element = jqLite(element); !

    // ... ! modules.unshift(['$provide', function($provide) { $provide.value('$rootElement', element); }]); modules.unshift('ng'); var injector = createInjector(modules, config.strictDi); injector.invoke(['$rootScope', '$rootElement', '$compile', '$injector function bootstrapApply(scope, element, compile, injector) { scope.$apply(function() { element.data('$injector', injector); compile(element)(scope); }); }] ); return injector; };
  117. 216.

    https://github.com/angular/angular.js/blob/master/src/Angular.js var doBootstrap = function() { element = jqLite(element); !

    // ... ! modules.unshift(['$provide', function($provide) { $provide.value('$rootElement', element); }]); modules.unshift('ng'); var injector = createInjector(modules, config.strictDi); injector.invoke(['$rootScope', '$rootElement', '$compile', '$injector function bootstrapApply(scope, element, compile, injector) { scope.$apply(function() { element.data('$injector', injector); compile(element)(scope); }); }] ); return injector; };
  118. 217.

    https://github.com/angular/angular.js/blob/master/src/Angular.js var doBootstrap = function() { element = jqLite(element); !

    // ... ! modules.unshift(['$provide', function($provide) { $provide.value('$rootElement', element); }]); modules.unshift('ng'); var injector = createInjector(modules, config.strictDi); injector.invoke(['$rootScope', '$rootElement', '$compile', '$injector function bootstrapApply(scope, element, compile, injector) { scope.$apply(function() { element.data('$injector', injector); compile(element)(scope); }); }] ); return injector; };
  119. 218.

    https://github.com/angular/angular.js/blob/master/src/Angular.js var doBootstrap = function() { element = jqLite(element); !

    // ... ! modules.unshift(['$provide', function($provide) { $provide.value('$rootElement', element); }]); modules.unshift('ng'); var injector = createInjector(modules, config.strictDi); injector.invoke(['$rootScope', '$rootElement', '$compile', '$injector function bootstrapApply(scope, element, compile, injector) { scope.$apply(function() { element.data('$injector', injector); compile(element)(scope); }); }] ); return injector; };
  120. 219.

    https://github.com/angular/angular.js/blob/master/src/Angular.js var doBootstrap = function() { element = jqLite(element); !

    // ... ! modules.unshift(['$provide', function($provide) { $provide.value('$rootElement', element); }]); modules.unshift('ng'); var injector = createInjector(modules, config.strictDi); injector.invoke(['$rootScope', '$rootElement', '$compile', '$injector function bootstrapApply(scope, element, compile, injector) { scope.$apply(function() { element.data('$injector', injector); compile(element)(scope); }); }] ); return injector; };
  121. 220.

    https://github.com/angular/angular.js/blob/master/src/Angular.js var doBootstrap = function() { element = jqLite(element); !

    // ... ! modules.unshift(['$provide', function($provide) { $provide.value('$rootElement', element); }]); modules.unshift('ng'); var injector = createInjector(modules, config.strictDi); injector.invoke(['$rootScope', '$rootElement', '$compile', '$injector function bootstrapApply(scope, element, compile, injector) { scope.$apply(function() { element.data('$injector', injector); compile(element)(scope); }); }] ); return injector; };
  122. 221.

    https://github.com/angular/angular.js/blob/master/src/Angular.js var doBootstrap = function() { element = jqLite(element); !

    // ... ! modules.unshift(['$provide', function($provide) { $provide.value('$rootElement', element); }]); modules.unshift('ng'); var injector = createInjector(modules, config.strictDi); injector.invoke(['$rootScope', '$rootElement', '$compile', '$injector function bootstrapApply(scope, element, compile, injector) { scope.$apply(function() { element.data('$injector', injector); compile(element)(scope); }); }] ); return injector; };
  123. 222.

    https://github.com/angular/angular.js/blob/master/src/Angular.js var doBootstrap = function() { element = jqLite(element); !

    // ... ! modules.unshift(['$provide', function($provide) { $provide.value('$rootElement', element); }]); modules.unshift('ng'); var injector = createInjector(modules, config.strictDi); injector.invoke(['$rootScope', '$rootElement', '$compile', '$injector function bootstrapApply(scope, element, compile, injector) { scope.$apply(function() { element.data('$injector', injector); compile(element)(scope); }); }] ); return injector; };
  124. 225.
  125. 226.

    // development.js app.invoke = function(fn) { var dom = document.querySelector('[ng-app="'

    + this.name + '"]'), element = angular.element(dom); ! return element.injector().invoke(fn); } 1
  126. 228.
  127. 230.
  128. 232.
  129. 233.
  130. 234.
  131. 235.
  132. 237.

    app.config(function($stateProvider) { $stateProvider .state('product', { url: '/product/:id', controller: ‘productCtrl', templateUrl:

    ‘product.html', resolve: { product: function($stateParams, Product) { return Product.get(id: $stateParams.id).$promise; } } }); });
  133. 238.

    app.config(function($stateProvider) { $stateProvider .state('product', { url: '/product/:id', controller: ‘productCtrl', templateUrl:

    ‘product.html', resolve: { product: function($stateParams, Product) { return Product.get(id: $stateParams.id).$promise; } } }); });
  134. 239.

    app.config(function($stateProvider) { $stateProvider .state('product', { url: '/product/:id', controller: ‘productCtrl', templateUrl:

    ‘product.html', resolve: { product: function($stateParams, Product) { return Product.get(id: $stateParams.id).$promise; } } }); });
  135. 240.

    app.config(function($stateProvider) { $stateProvider .state('product', { url: '/product/:id', controller: ‘productCtrl', templateUrl:

    ‘product.html', resolve: { product: function($stateParams, Product) { return Product.get(id: $stateParams.id).$promise; } } }); });
  136. 241.

    app.config(function($stateProvider) { $stateProvider .state('product', { url: '/product/:id', controller: ‘productCtrl', templateUrl:

    ‘product.html', resolve: { product: function($stateParams, Product) { return Product.get(id: $stateParams.id).$promise; } } }); });
  137. 242.

    app.config(function($stateProvider) { $stateProvider .state('product', { url: '/product/:id', controller: ‘productCtrl', templateUrl:

    ‘product.html', resolve: { product: function($stateParams, Product) { return Product.get(id: $stateParams.id).$promise; } } }); });
  138. 243.

    app.config(function($stateProvider) { $stateProvider .state('product', { url: '/product/:id', controller: ‘productCtrl', templateUrl:

    ‘product.html', resolve: { product: function($stateParams, Product) { return Product.get(id: $stateParams.id).$promise; } } }); });
  139. 244.

    app.config(function($stateProvider) { $stateProvider .state('product', { url: '/product/:id', controller: ‘productCtrl', templateUrl:

    ‘product.html', resolve: { product: function($stateParams, Product) { return Product.get(id: $stateParams.id).$promise; } } }); });
  140. 245.

    app.config(function($stateProvider) { $stateProvider .state('product', { url: '/product/:id', controller: ‘productCtrl', templateUrl:

    ‘product.html', resolve: { product: function($stateParams, Product) { return Product.get(id: $stateParams.id).$promise; } } }); });
  141. 251.

    ui-sref https://github.com/angular-ui/ui-router/wiki/Quick-Reference#ui-sref <a ui-sref="home">Home</a> | <a ui-sref="about">About</a> ! <ul> <li

    ng-repeat="contact in contacts"> <a ui-sref="contacts.show({id: contact.id})"> {{contact.name}} </a> </li> </ul>
  142. 252.

    ui-sref https://github.com/angular-ui/ui-router/wiki/Quick-Reference#ui-sref <a ui-sref="home">Home</a> | <a ui-sref="about">About</a> ! <ul> <li

    ng-repeat="contact in contacts"> <a ui-sref="contacts.show({id: contact.id})"> {{contact.name}} </a> </li> </ul>
  143. 253.

    ui-sref https://github.com/angular-ui/ui-router/wiki/Quick-Reference#ui-sref <a ui-sref="home">Home</a> | <a ui-sref="about">About</a> ! <ul> <li

    ng-repeat="contact in contacts"> <a ui-sref="contacts.show({id: contact.id})"> {{contact.name}} </a> </li> </ul>
  144. 254.

    ui-sref https://github.com/angular-ui/ui-router/wiki/Quick-Reference#ui-sref <a ui-sref="home">Home</a> | <a ui-sref="about">About</a> ! <ul> <li

    ng-repeat="contact in contacts"> <a ui-sref="contacts.show({id: contact.id})"> {{contact.name}} </a> </li> </ul>
  145. 255.

    ui-sref https://github.com/angular-ui/ui-router/wiki/Quick-Reference#ui-sref <a ui-sref="home">Home</a> | <a ui-sref="about">About</a> ! <ul> <li

    ng-repeat="contact in contacts"> <a ui-sref="contacts.show({id: contact.id})"> {{contact.name}} </a> </li> </ul>
  146. 256.

    2.0

  147. 258.

    app.config(function($stateProvider) { $stateProvider .state('product', { url: '/product/:id', controller: ‘productCtrl', templateUrl:

    ‘product.html', resolve: { product: function($stateParams, Product) { return Product.get(id: $stateParams.id).$promise; } } }); });
  148. 259.

    app.config(function($stateProvider) { $stateProvider .state('product', { url: '/product/:id', controller: ‘productCtrl', templateUrl:

    ‘product.html', resolve: { product: function($stateParams, Product) { return Product.get(id: $stateParams.id).$promise; } } }); });
  149. 260.

    app.config(function($stateProvider) { $stateProvider .state('product', { url: '/product/:id', controller: ‘productCtrl', templateUrl:

    ‘product.html', resolve: { product: function($stateParams, Product) { return Product.get(id: $stateParams.id).$promise; } } }); });
  150. 261.

    app.config(function($httpProvider) { var CODE_MAPPING = { 401: '/errors/unauthorized', 404: ‘/errors/not_found'

    }; ! $httpProvider.interceptors.push(function($q, $location) { return { 'responseError': function(rejection) { var path = CODE_MAPPING[rejection.status]; if (path) { return $location.path(path); } else { return $q.reject(rejection); } } }; }); }); 3
  151. 262.

    app.config(function($httpProvider) { var CODE_MAPPING = { 401: '/errors/unauthorized', 404: ‘/errors/not_found'

    }; ! $httpProvider.interceptors.push(function($q, $location) { return { 'responseError': function(rejection) { var path = CODE_MAPPING[rejection.status]; if (path) { return $location.path(path); } else { return $q.reject(rejection); } } }; }); }); 3
  152. 263.

    app.config(function($httpProvider) { var CODE_MAPPING = { 401: '/errors/unauthorized', 404: ‘/errors/not_found'

    }; ! $httpProvider.interceptors.push(function($q, $location) { return { 'responseError': function(rejection) { var path = CODE_MAPPING[rejection.status]; if (path) { return $location.path(path); } else { return $q.reject(rejection); } } }; }); }); 3
  153. 264.

    app.config(function($httpProvider) { var CODE_MAPPING = { 401: '/errors/unauthorized', 404: ‘/errors/not_found'

    }; ! $httpProvider.interceptors.push(function($q, $location) { return { 'responseError': function(rejection) { var path = CODE_MAPPING[rejection.status]; if (path) { return $location.path(path); } else { return $q.reject(rejection); } } }; }); }); 3
  154. 265.

    app.config(function($httpProvider) { var CODE_MAPPING = { 401: '/errors/unauthorized', 404: ‘/errors/not_found'

    }; ! $httpProvider.interceptors.push(function($q, $location) { return { 'responseError': function(rejection) { var path = CODE_MAPPING[rejection.status]; if (path) { return $location.path(path); } else { return $q.reject(rejection); } } }; }); }); 3
  155. 266.

    app.config(function($httpProvider) { var CODE_MAPPING = { 401: '/errors/unauthorized', 404: ‘/errors/not_found'

    }; ! $httpProvider.interceptors.push(function($q, $location) { return { 'responseError': function(rejection) { var path = CODE_MAPPING[rejection.status]; if (path) { return $location.path(path); } else { return $q.reject(rejection); } } }; }); }); 3
  156. 267.

    app.config(function($httpProvider) { var CODE_MAPPING = { 401: '/errors/unauthorized', 404: ‘/errors/not_found'

    }; ! $httpProvider.interceptors.push(function($q, $location) { return { 'responseError': function(rejection) { var path = CODE_MAPPING[rejection.status]; if (path) { return $location.path(path); } else { return $q.reject(rejection); } } }; }); }); 3
  157. 268.

    app.config(function($httpProvider) { var CODE_MAPPING = { 401: '/errors/unauthorized', 404: ‘/errors/not_found'

    }; ! $httpProvider.interceptors.push(function($q, $location) { return { 'responseError': function(rejection) { var path = CODE_MAPPING[rejection.status]; if (path) { return $location.path(path); } else { return $q.reject(rejection); } } }; }); }); 3
  158. 269.

    app.config(function($httpProvider) { var CODE_MAPPING = { 401: '/errors/unauthorized', 404: ‘/errors/not_found'

    }; ! $httpProvider.interceptors.push(function($q, $location) { return { 'responseError': function(rejection) { var path = CODE_MAPPING[rejection.status]; if (path) { return $location.path(path); } else { return $q.reject(rejection); } } }; }); }); 3
  159. 270.

    app.config(function($httpProvider) { var CODE_MAPPING = { 401: '/errors/unauthorized', 404: ‘/errors/not_found'

    }; ! $httpProvider.interceptors.push(function($q, $location) { return { 'responseError': function(rejection) { var path = CODE_MAPPING[rejection.status]; if (path) { return $location.path(path); } else { return $q.reject(rejection); } } }; }); }); 3
  160. 271.

    app.config(function($httpProvider) { var CODE_MAPPING = { 401: '/errors/unauthorized', 404: ‘/errors/not_found'

    }; ! $httpProvider.interceptors.push(function($q, $location) { return { 'responseError': function(rejection) { var path = CODE_MAPPING[rejection.status]; if (path) { return $location.path(path); } else { return $q.reject(rejection); } } }; }); }); 3
  161. 272.
  162. 274.

    4 app.directive('simpleFileUpload', function() { return { require: '?ngModel', link: function(scope,

    element, attrs, ngModel) { return element.on('change', function(event) { return scope.$apply(function() { return ngModel.$setViewValue(event.target.files[0]); }); }); } }; });
  163. 275.

    4 app.directive('simpleFileUpload', function() { return { require: '?ngModel', link: function(scope,

    element, attrs, ngModel) { return element.on('change', function(event) { return scope.$apply(function() { return ngModel.$setViewValue(event.target.files[0]); }); }); } }; });
  164. 276.

    4 app.directive('simpleFileUpload', function() { return { require: '?ngModel', link: function(scope,

    element, attrs, ngModel) { return element.on('change', function(event) { return scope.$apply(function() { return ngModel.$setViewValue(event.target.files[0]); }); }); } }; });
  165. 277.

    4 app.directive('simpleFileUpload', function() { return { require: '?ngModel', link: function(scope,

    element, attrs, ngModel) { return element.on('change', function(event) { return scope.$apply(function() { return ngModel.$setViewValue(event.target.files[0]); }); }); } }; });
  166. 278.

    4 app.directive('simpleFileUpload', function() { return { require: '?ngModel', link: function(scope,

    element, attrs, ngModel) { return element.on('change', function(event) { return scope.$apply(function() { return ngModel.$setViewValue(event.target.files[0]); }); }); } }; });
  167. 279.

    4 app.directive('simpleFileUpload', function() { return { require: '?ngModel', link: function(scope,

    element, attrs, ngModel) { return element.on('change', function(event) { return scope.$apply(function() { return ngModel.$setViewValue(event.target.files[0]); }); }); } }; });
  168. 280.

    4 app.directive('simpleFileUpload', function() { return { require: '?ngModel', link: function(scope,

    element, attrs, ngModel) { return element.on('change', function(event) { return scope.$apply(function() { return ngModel.$setViewValue(event.target.files[0]); }); }); } }; });
  169. 281.

    4 app.directive('simpleFileUpload', function() { return { require: '?ngModel', link: function(scope,

    element, attrs, ngModel) { return element.on('change', function(event) { return scope.$apply(function() { return ngModel.$setViewValue(event.target.files[0]); }); }); } }; });
  170. 282.

    4 app.directive('simpleFileUpload', function() { return { require: '?ngModel', link: function(scope,

    element, attrs, ngModel) { return element.on('change', function(event) { return scope.$apply(function() { return ngModel.$setViewValue(event.target.files[0]); }); }); } }; });
  171. 284.

    <my-panel title="'Description'"> <p>Long text</p> <p>Very long text</p> <p>Very very long

    text</p> <p>Even longer text than the very very long text</p> </my-panel>
  172. 285.

    <my-panel title="'Description'"> <p>Long text</p> <p>Very long text</p> <p>Very very long

    text</p> <p>Even longer text than the very very long text</p> </my-panel>
  173. 286.

    <my-panel title="'Description'"> <p>Long text</p> <p>Very long text</p> <p>Very very long

    text</p> <p>Even longer text than the very very long text</p> </my-panel>
  174. 287.

    <my-panel title="'Description'"> <p>Long text</p> <p>Very long text</p> <p>Very very long

    text</p> <p>Even longer text than the very very long text</p> </my-panel>
  175. 288.

    <my-panel title="'Description'"> <p>Long text</p> <p>Very long text</p> <p>Very very long

    text</p> <p>Even longer text than the very very long text</p> </my-panel>
  176. 289.

    ! ! <div class="panel panel-default"> <div class="panel-heading">Description</div> <div class="panel-body"> <p>Long

    text</p> <p>Very long text</p> <p>Very very long text</p> <p>Even longer text than the very very long text</p> </div> </div>
  177. 290.

    ! ! <div class="panel panel-default"> <div class="panel-heading">Description</div> <div class="panel-body"> <p>Long

    text</p> <p>Very long text</p> <p>Very very long text</p> <p>Even longer text than the very very long text</p> </div> </div>
  178. 291.

    ! ! <div class="panel panel-default"> <div class="panel-heading">Description</div> <div class="panel-body"> <p>Long

    text</p> <p>Very long text</p> <p>Very very long text</p> <p>Even longer text than the very very long text</p> </div> </div>
  179. 292.

    5 app.directive('myPanel', function() { return { restrict: 'E', transclude: true,

    scope: { title: '=title' }, template: '<div class="panel panel-default">' + '<div class="panel-heading">{{title}}</div>' + '<div class="panel-body" ng-transclude></div>' + '</div>' }; });
  180. 293.

    5 app.directive('myPanel', function() { return { restrict: 'E', transclude: true,

    scope: { title: '=title' }, template: '<div class="panel panel-default">' + '<div class="panel-heading">{{title}}</div>' + '<div class="panel-body" ng-transclude></div>' + '</div>' }; });
  181. 294.

    5 app.directive('myPanel', function() { return { restrict: 'E', transclude: true,

    scope: { title: '=title' }, template: '<div class="panel panel-default">' + '<div class="panel-heading">{{title}}</div>' + '<div class="panel-body" ng-transclude></div>' + '</div>' }; });
  182. 295.

    5 app.directive('myPanel', function() { return { restrict: 'E', transclude: true,

    scope: { title: '=title' }, template: '<div class="panel panel-default">' + '<div class="panel-heading">{{title}}</div>' + '<div class="panel-body" ng-transclude></div>' + '</div>' }; });
  183. 296.

    5 app.directive('myPanel', function() { return { restrict: 'E', transclude: true,

    scope: { title: '=title' }, template: '<div class="panel panel-default">' + '<div class="panel-heading">{{title}}</div>' + '<div class="panel-body" ng-transclude></div>' + '</div>' }; });
  184. 297.

    5 app.directive('myPanel', function() { return { restrict: 'E', transclude: true,

    scope: { title: '=title' }, template: '<div class="panel panel-default">' + '<div class="panel-heading">{{title}}</div>' + '<div class="panel-body" ng-transclude></div>' + '</div>' }; });
  185. 298.

    5 app.directive('myPanel', function() { return { restrict: 'E', transclude: true,

    scope: { title: '=title' }, template: '<div class="panel panel-default">' + '<div class="panel-heading">{{title}}</div>' + '<div class="panel-body" ng-transclude></div>' + '</div>' }; });
  186. 299.

    5 app.directive('myPanel', function() { return { restrict: 'E', transclude: true,

    scope: { title: '=title' }, template: '<div class="panel panel-default">' + '<div class="panel-heading">{{title}}</div>' + '<div class="panel-body" ng-transclude></div>' + '</div>' }; });
  187. 300.

    5 app.directive('myPanel', function() { return { restrict: 'E', transclude: true,

    scope: { title: '=title' }, template: '<div class="panel panel-default">' + '<div class="panel-heading">{{title}}</div>' + '<div class="panel-body" ng-transclude></div>' + '</div>' }; });
  188. 301.

    <my-panel title="'Description'"> <p>Long text</p> <p>Very long text</p> <p>Very very long

    text</p> <p>Even longer text than the very very long text</p> </my-panel>
  189. 302.

    ! ! <div class="panel panel-default"> <div class="panel-heading">Description</div> <div class="panel-body"> <p>Long

    text</p> <p>Very long text</p> <p>Very very long text</p> <p>Even longer text than the very very long text</p> </div> </div>
  190. 304.

    https://github.com/angular/angular.js/blob/master/src/ng/directive/ngShowHide.js var ngShowDirective = ['$animate', function($animate) { return { restrict:

    'A', multiElement: true, link: function(scope, element, attr) { scope.$watch(attr.ngShow, function ngShowWatchAction(value){ $animate[value ? 'removeClass' : 'addClass'](element, 'ng-hide') }); } }; }];
  191. 305.

    https://github.com/angular/angular.js/blob/master/src/ng/directive/ngShowHide.js var ngShowDirective = ['$animate', function($animate) { return { restrict:

    'A', multiElement: true, link: function(scope, element, attr) { scope.$watch(attr.ngShow, function ngShowWatchAction(value){ $animate[value ? 'removeClass' : 'addClass'](element, 'ng-hide') }); } }; }];
  192. 306.

    https://github.com/angular/angular.js/blob/master/src/ng/directive/ngShowHide.js var ngShowDirective = ['$animate', function($animate) { return { restrict:

    'A', multiElement: true, link: function(scope, element, attr) { scope.$watch(attr.ngShow, function ngShowWatchAction(value){ $animate[value ? 'removeClass' : 'addClass'](element, 'ng-hide') }); } }; }];
  193. 307.

    https://github.com/angular/angular.js/blob/master/src/ng/directive/ngShowHide.js var ngShowDirective = ['$animate', function($animate) { return { restrict:

    'A', multiElement: true, link: function(scope, element, attr) { scope.$watch(attr.ngShow, function ngShowWatchAction(value){ $animate[value ? 'removeClass' : 'addClass'](element, 'ng-hide') }); } }; }];
  194. 308.

    https://github.com/angular/angular.js/blob/master/src/ng/directive/ngShowHide.js var ngShowDirective = ['$animate', function($animate) { return { restrict:

    'A', multiElement: true, link: function(scope, element, attr) { scope.$watch(attr.ngShow, function ngShowWatchAction(value){ $animate[value ? 'removeClass' : 'addClass'](element, 'ng-hide') }); } }; }];
  195. 309.

    https://github.com/angular/angular.js/blob/master/src/ng/directive/ngShowHide.js var ngShowDirective = ['$animate', function($animate) { return { restrict:

    'A', multiElement: true, link: function(scope, element, attr) { scope.$watch(attr.ngShow, function ngShowWatchAction(value){ $animate[value ? 'removeClass' : 'addClass'](element, 'ng-hide') }); } }; }];
  196. 310.

    https://github.com/angular/angular.js/blob/master/src/ng/directive/ngShowHide.js var ngShowDirective = ['$animate', function($animate) { return { restrict:

    'A', multiElement: true, link: function(scope, element, attr) { scope.$watch(attr.ngShow, function ngShowWatchAction(value){ $animate[value ? 'removeClass' : 'addClass'](element, 'ng-hide') }); } }; }];
  197. 311.

    https://github.com/angular/angular.js/blob/master/src/ng/directive/ngShowHide.js var ngShowDirective = ['$animate', function($animate) { return { restrict:

    'A', multiElement: true, link: function(scope, element, attr) { scope.$watch(attr.ngShow, function ngShowWatchAction(value){ $animate[value ? 'removeClass' : 'addClass'](element, 'ng-hide') }); } }; }];
  198. 312.

    https://github.com/angular/angular.js/blob/master/src/ng/directive/ngShowHide.js var ngShowDirective = ['$animate', function($animate) { return { restrict:

    'A', multiElement: true, link: function(scope, element, attr) { scope.$watch(attr.ngShow, function ngShowWatchAction(value){ $animate[value ? 'removeClass' : 'addClass'](element, 'ng-hide') }); } }; }];
  199. 313.

    https://github.com/angular/angular.js/blob/master/src/ng/directive/ngIf.js var ngIfDirective = ['$animate', function($animate) { return { transclude:

    'element', // ... settings link: function ($scope, $element, $attr, ctrl, $transclude) { $scope.$watch($attr.ngIf, function ngIfWatchAction(value) { if (value) { // add content from page } else { // remove content from page } }); } }; }];
  200. 314.

    https://github.com/angular/angular.js/blob/master/src/ng/directive/ngIf.js var ngIfDirective = ['$animate', function($animate) { return { transclude:

    'element', // ... settings link: function ($scope, $element, $attr, ctrl, $transclude) { $scope.$watch($attr.ngIf, function ngIfWatchAction(value) { if (value) { // add content from page } else { // remove content from page } }); } }; }];
  201. 315.

    https://github.com/angular/angular.js/blob/master/src/ng/directive/ngIf.js var ngIfDirective = ['$animate', function($animate) { return { transclude:

    'element', // ... settings link: function ($scope, $element, $attr, ctrl, $transclude) { $scope.$watch($attr.ngIf, function ngIfWatchAction(value) { if (value) { // add content from page } else { // remove content from page } }); } }; }];
  202. 316.

    https://github.com/angular/angular.js/blob/master/src/ng/directive/ngIf.js var ngIfDirective = ['$animate', function($animate) { return { transclude:

    'element', // ... settings link: function ($scope, $element, $attr, ctrl, $transclude) { $scope.$watch($attr.ngIf, function ngIfWatchAction(value) { if (value) { // add content from page } else { // remove content from page } }); } }; }];
  203. 317.

    https://github.com/angular/angular.js/blob/master/src/ng/directive/ngIf.js var ngIfDirective = ['$animate', function($animate) { return { transclude:

    'element', // ... settings link: function ($scope, $element, $attr, ctrl, $transclude) { $scope.$watch($attr.ngIf, function ngIfWatchAction(value) { if (value) { // add content from page } else { // remove content from page } }); } }; }];
  204. 318.

    https://github.com/angular/angular.js/blob/master/src/ng/directive/ngIf.js var ngIfDirective = ['$animate', function($animate) { return { transclude:

    'element', // ... settings link: function ($scope, $element, $attr, ctrl, $transclude) { $scope.$watch($attr.ngIf, function ngIfWatchAction(value) { if (value) { // add content from page } else { // remove content from page } }); } }; }];
  205. 319.

    https://github.com/angular/angular.js/blob/master/src/ng/directive/ngIf.js var ngIfDirective = ['$animate', function($animate) { return { transclude:

    'element', // ... settings link: function ($scope, $element, $attr, ctrl, $transclude) { $scope.$watch($attr.ngIf, function ngIfWatchAction(value) { if (value) { // add content from page } else { // remove content from page } }); } }; }];
  206. 321.
  207. 329.
  208. 332.
  209. 333.
  210. 335.