Don't wanna be here? Send us removal request.
Text
AngularJS Notes (17)
Study Notes of “The Complete Book on AngularJS”
Chapter 17: Promises
17.1 What’s a Promise?
A promise is a method of resolving a value (or not) in an asynchronous manner. Promises are objects that represent the return value or thrown exception that a function may eventually provide.
We can guarantee that the callback will resolve to a single value, rather than having to deal with the callback interface.
17.2 Why promise?
The real point of promises is to make asynchronous functions look more like synchronous ones.
The point of using promises is to regain the ability to do functional composition and error bubbling while maintaining the ability of the code to run asynchronously.
17.3 Promises in Angular
Resolve promises in its $rootScope.$evalAsync stage
How to Create a Promise
var deferred = $q.defer();
The deferred object exposes three methods and the single promise property that we can use to deal with the promise.
resolve(value)
reject(reason)
notify(value)
Ways to interact with the promise:
1. then(successFn, errFn, notifyFn)
The then() method always returns a new promise, which is either resolved or rejected through the return value of the successFn or the errFn.
2. catch(errFn)
This method is simply a helper function that allows for us to replace the err callback with .catch(function(reason) {})
3. finally(callback)
promise['finally'](function() {});
17.4 Chaining Requests
17.4.1 all (promises)
Combine multiple promises into a single promise.
17.4.2 defer ( )
Creates a deferred object.
17.4.3 reject (reason)
This method creates a promise that is resolved with a rejection for a specific reason. It is specifically designed to give us access to forwarding rejection in a chain of promises, which is akin to throw in JavaScript.
17.4.4 when (value)
The when( ) function wraps an object that might be a value then-able promise into a $q promise.
0 notes
Text
AngularJS Notes (16 - 2)
Study Notes of “The Complete Book on AngularJS”
Chapter 16: XHR in Practice
16.5 Working with JSON
JavaScript Object Notation, Angular will resolve any requests that respond with a JavaScript object in JSON format to a corresponding object for our Angular app.
16.6 Working with XML
Some built-in browser parsers that parse XML into JavaScript objects for us. e.g. X2JS.
16.7 Authentication with AngularJS
16.7.1 Server-Side Requirements
First and foremost, we must take the time to secure our server-side API. Two ways:
1. Server-Side Rendered Views
Back-end server controls all of the HTML
2. Pure Client-Side Authentication
Auth token.
Response status codes:

16.7.2 Client-Side Authentication
Ways to handle defining routes as public vs. non-public.
1. Protected Resources from API
Interceptor

To actually implement this interceptor for our requests, we need to tell the $httpProvider to include it in its interceptor chain.
$httpProvider.interceptors.push(interceptor);
2. Protected Resources by Route Definition
In order to monitor our routes, we must set up an event listener on the $routeChangeStart event.
Access_level.
To authenticate a user, we need to create a service that holds onto the existing user level. We must also let our service work with the local browser cookie store.
16.8 Talking to MongoDB
Without a custom back end, it’s also possible to talk directly to a database that exposes a RESTful interface.

0 notes
Text
AngularJS Notes (16 - 1)
Study Notes of “The Complete Book on AngularJS”
Chapter 16: XHR in Practice
16.1 Cross-Origin and Same-Origin Policy
Cross Origin Resource Sharing (or CORS, for short)
16.2 JSONP
JSONP is a way to get past the browser security issues that are present when we’re trying to request data from a foreign domain. In order to work with JSONP, the server must be able to support the method.
JSONP works by issuing a GET request using a <script> tag, instead of using XHR requests. The JSONP technique creates a <script> tag and places it in the DOM. When it shows up in the DOM, the browser takes over and requests the script referenced in the src tag.
Angular provides a helper for JSONP requests using the $http service.
$http .jsonp("https://api.github.com?callback=JSON_CALLBACK") .success(function(data) {...});
When we make this call, Angular places a <script> tag on the DOM that might look something like:
<script src="https://api.github.com?callback=angular.callbacks._0" type="text/javascript"></script>
Angular has replaced the JSON_CALLBACK with a custom function that Angular creates specifically for this request. When the data comes back from the JSONP-enabled server, it is wrapped in the anonymous function automatically generated by Angular angular.callbacks._0
16.3 Using CORS
The CORS specification is simply an extension to the standard XMLHttpRequest object that allows JavaScript to make cross-domain XHR calls. It does so by preflighting a request to the server to effectively ask for permission to send the request.
16.3.1 Configuration
Tell Angular to use the XDomain.
Remove the X-Requested-With header from all of our requests.
angular.module('myApp') .config(function($httpProvider) { $httpProvider.defaults.useXDomain = true; delete $httpProvider.defaults.headers .common['X-Requested-With']; });
16.3.2 Server CORS Requirements
A server supporting CORS must respond to requests with several access control headers:
Access-Control-Allow-Origin
Access-Control-Allow-Credentials (optional)
16.3.3 Simple Requests
Requests are simple if they match one of these HTTP methods:
HEAD
GET
POST
and if they are made with one or many of the following HTTP headers, and no others:
Accept
Accept-Language
Content-Language
Last-Event-ID
Content-Type
application/x-www-form-urlencoded
multipart/form-data
text/plain
The browser can make these types of requests without the use of CORS. Simple requests do NOT require any special type of communication between the server and the client.
$http .get("https://api.github.com") .success(function(data) { ... });
16.3.4 Non-Simple Request
If we want to support PUT or DELETE methods, or if we want to set the specific type of content type in our requests, then we’re going to call a non-simple request. The browser actually sends two requests: the preflight and the request.
$http .delete("https://api.github.com/api/users/1") .success(function(data) { ... });
16.4 Server-Side Proxies
The simplest method for making requests to any server, however, is to simply use a back-end server on the same domain (or on a remote server with CORS setup) as a proxy for remote resources.
In order to use a server-side proxy, we need to set up a local server to handle our requests, which takes care of sending the actual requests.
0 notes
Text
AngularJS Notes (15 - 4)
Study Notes of “The Complete Book on AngularJS”
Chapter 15: Communicating with the Outside World: XHR and Server-Side Communication
15.13 Using Rectangular
Library: talk with the outside world.
15.14 The What and the Why
Restangular is an Angular service specifically designed simply to fetch data from the rest of the world.
Benefits:
Promise: to chain together responses
Promise Unwrapping: use Restangular as $resource works
Explicit
All HTTP Methods
Forget URLs
Nested Resources
One resource, not many
15.15 Installation
Github or $ npm install restangular.
Note: Restangular depends on either Lo-Dash or Underscore.
15.16 Into to the Restangular Object
Two ways we can create an object to fetch services:
1. set the base route to fetch objects from
var User = Restangular.all('users'); var allUsers = User.getList();
2. pass a unique ID to pull from
var oneUser = Restangular.one('users', 'abc123'); oneUser.get().then(function(user) { user.getList('inboxes'); });
15.7 Using Restangular
var messages = Restangular.all('messages');
1. get
var allMessages = messages.getList();
2. post
var newMessage = { body: "Hello world"}; messages.post(newMessage);
OR:
var message = Restangular.one('messages', 'abc123'); message.post('replies', newMessage);
Restangular returns enhanced promises, so besides being able to call then on them, we can call other special methods like $object. $object returns an empty array (or object) right away, and after the server returns information, that array is filled with new information.
$scope.messages = messages.getList().$object;
3. remove
var message = messages.get(123); message.remove();
4. put
15.7.1 But What About My HTTP Methods?
Restangular supports, out of the box, all HTTP methods. It can support calling GET, PUT, POST, DELETE, HEAD, TRACE, OPTIONS, and PATCH.
Restangular also makes it possible to create custom HTTP methods for cases when our back-end server maps resources differently than we expect.
15.7.2 Custom Query Parameters and Headers
messages.getList('accounts', queryParamObj, headerObj);
15.8 Configuring Restangular
To configure Restangular for all Restangular usages, regardless of the location it’s used in, we can inject the RestangularProvider in a config() function or inject Restangular in a run() function.
Setting the BaseUrl .setBaseUrl
Adding Element Transformations .addElementTransformer .extendModel
Setting ResponseInterceptors .setResponseInterceptor
Using requestInterceptors .setRequestInterceptor
Custom Fields .setRestangularFields
Catching Errors with errorInterceptors .setErrorInterceptor
Setting Parentless .setParentless
Working with Hypermedia selfLink, oneUrl and allUrl.
0 notes
Text
AngularJS Notes (15 - 3)
Study Notes of “The Complete Book on AngularJS”
Chapter 15: Communicating with the Outside World: XHR and Server-Side Communication
15.7 Using $resource
$resource service creates a resource object that allows us to intelligently work with RESTful server-side data sources.
15.8 Installation
$ bower install –save angular-resouce
angular.module('myApp’, ['ngResource’]);
15.9 Using $resource
The $resource service itself is a factory that creates a resource object. The returned $resource object has methods that provide a high-level API to interact with back-end servers.
var User = $resource(’/api/users/:userId.json’, { userId: ’@id’ } );
$resource returns a resource class object with a few methods for default actions. We can think of the User object as an interface to our RESTful back-end services.
15.9.1 HTTP GET Methods
1. get(params, successFn, errorFn)
The get method sends a GET request to the URL and expects a JSON response.
User.get({ id: '123’}, function(resp) {…}, function(err) {…});
2. query(params, successFn, errorFn)
The query method sends a GET request to the URL and expects a collection of resource objects as a JSON response array.
User.query(function(users) { var user = users[0]; });
The only major difference between the query() method and the get() method is that Angular expects the query() method to return an array.
15.9.2 HTTP Non-GET Methods
1. save(params, payload, successFn, errorFn)
The save method sends a POST request to the URL and uses the payload to generate the request body. The save() method is used to create a new resource on the server.
User.save({}, { name: 'Ari' }, function(response) {…}, function(response) {…});
2. delete(params, payload, successFn, errorFn)
The delete method sends a DELETE request to the URL and can use the payload to generate the request body. It is used to remove an instance from the server.
3. remove(params, payload, successFn, errorFn)
The remove method is synonymous with the delete() method and primarily exists because delete is a reserved word in JavaScript that can cause problems when we use in Internet Explorer.
15.9.3 $resource instances
When the methods above return data, they wrap the response in a prototype class that adds convenience methods on the instances.
$save()
$remove()
$delete()
15.9.4 $resource Instances Are Asynchronous
When these methods are invoked, the $resource object immediately returns an empty reference to the data.
15.9.5 Additional Properties
The $resource collections and instances have two special properties that enable us to interact with the underlying resource definitions.
$promise (promise)
$resolved (boolean)
15.10 Custom $resource Methods
To create a custom method on our $resource class object, we can pass a third argument to the resource class that contains an object of a modified $http configuration object as methods.
In the object, the key is the name of the method and the value is the $http configuration object.
15.11 $resource Configuration Object
Very similar to the $http. It can contains the following keys:
method (string): ‘GET’, ‘DELETE’, ‘JSONP’, ‘POST’, ‘PUT’.
url (string)
params (map of string/object)
isArray (boolean)
transformRequest (function/array of functions): usually used for serialization.
transformResponse (function/array of functions): usually used for deserialization.
cache (boolean/cache)
timeout (number/promise)
withCredentials (boolean)
responseType (string)
interceptor (object)
15.12 $resource Services
We can use the $resource service as the base our own custom services.
angular.module('myApp', ['ngResource']) .factory('UserService', ['$resource', function($resource) { return $resource('/api/users/:id', { id: '@' }, {update: {method: 'PUT'}}); } ]);
$resource API
The $resource service is available through the use of the $resource() method. The method itself takes up to three parameters:
url (string)
paramDefaults (optional object)
actions (optional object)
$resource('/api/users/:id.:format', { format: 'json', id: '123' }, { update: {method: 'PUT'} })
0 notes
Text
OO Design (1)
From Intersystems e-learning:
http://video.intersystems.com/video/Video.Pages.VideoLibrary.cls?video=750177471001&showpl=1&setaa=1
Procedures:
Document requirements
Identify objects - Nouns
Generalize objects - Group them.
Define data properties - nouns.
Define actions/logic needed to manipulate the object - Verbs.
Example:
A doctor’s office would like to create an application to handle appointments and maintain information on employees and patients.
1. Document
Doctors: salary, SSN, home address, phone number, days they began to work, specialty.
Administrators: title.
Patients: home address, phone number, SSN, medical history.
Appointment: date, time, doctor, patient, which admin booked.
Admins book appointments and delete appointments if a patient calls to cancel.
When a patient comes in for an appointment, the doctor must retrieve their medical history.
At the end of each day, an admin prints all the appointments for the following day, so that each doctor knows when to come to the office.
2. Identify objects - Nouns
Find the BIG “things” in the requirements.
doctors, patients, admins, appointments, address.
3. Generalize objects
Decide if you can place common elements in a superclass and use inheritance. (IS-A).
Person <- Employee
4. Define data properties - nouns
Look for the LITTLE nouns which describe elements of the BIG nouns.

5. Define actions/logic needed to manipulate the object - Verbs
Instance Method: Operator on a specific object instance.
Book appointments, Delete appointments, Display patient history
Class Method: Operator on more that one object instance.
Print all appointments.

0 notes
Text
AngularJS Notes (15 - 2)
Study Notes of “The Complete Book on AngularJS”
Chapter 15: Communicating with the Outside World: XHR and Server-Side Communication
15.4 Caching HTTP Requests
$http.get('/api/users.json', { cache: true })
For more custom control of the cache that Angular uses, we can pass a custom cache instead of true in the request.
Can also use config to set up a default cache.
angular.module('myApp', []) .config(function($httpProvider, $cacheFactory) { $httpProvider.defaults.cache = $cacheFactory('lru', {capacity: 20}); });
15.5 Interceptors
Anytime that we want to provide global functionality on all of our requests, such as authentication, error handling, etc., it’s useful to be able to provide the ability to intercept all requests before they pass to the server and back from the server.
Interceptors are:
basically middleware for the $http service that allow us to inject logic into the existing flow of the app.
service factories (.factory) that we register through the $httpProvider by adding them to the $httpProvider.
Four types of interceptors:
request
response
requestError
responseError
angular.module('myApp') .factory('myInterceptor', function($q) { var interceptor = { 'request': function(config) {...}, } };
angular.module('myApp') .config(function($httpProvider) { $httpProvider.interceptors.push('myInterceptor'); });
15.6 Configuring the $httpProvider
Using the .config() option, we can add certain HTTP headers to every request.
angular.module('myApp') .config(function($httpProvider) { $httpProvider.defaults.headers .common['X-Requested-By'] = 'MyAngularApp'; });
We can also manipulate these defaults at run time using the defaults property of the $http object.
$http.defaults.common['X-Auth'] = "RandomString";
0 notes
Text
AngularJS Notes (15 - 1)
Study Notes of “The Complete Book on AngularJS”
Chapter 15: Communicating with the Outside World: XHR and Server-Side Communication
15.1 Using $http
The $http service is simply a wrapper around the browser’s raw XMLHttpRequest object.
The $http service is a function that takes a single argument: a configuration object that is used to generate a HTTP request. The function returns a promise that has two helper methods: success and error.
promise.then( function(resp) { // resp is a response object}, function(resp) { // resp with error} );
OR we can use the success/error methods:
promise.success( function(data, status, headers, config) { // Handle successful resp}); promise.error( function(data, status, headers, config) { // Handle non-successful resp});
The difference between using the then() method and the convenience helpers is that the success() and error() functions contain a destructured representation of the response object, which the then() method receives in whole.
To execute an $http function outside of the $digest loop, we need to wrap it in an $apply block.
$scope.$apply(function() { $http({...});});
Shortcut Methods
shorten any method calls that don’t require more customization than a URL and a method name
$http.get('/api/users.json'); $http.jsonp("/api/users.json?callback=JSON_CALLBACK");
get( )
delete( )
head( )
jsonp( )
post( )
put( )
15.2 Configuration Object
Describes how to craft the XMLHttpRequest object. Contains the following keys:
method (string): ‘GET’, ‘DELETE’, ‘HEAD’, ‘JSONP’, ‘POST’, ‘PUT’.
url (string): absolute or relative URL.
params (map of strings/objects): If the value is not a string, it will be JSONified.
data (string/object)
headers (object)
xsrfHeaderName (string)
xsrfCookieName (string)
transformRequest (function/array of functions)
transformResponse (function/array of functions)
cache (boolean/Cache object)
timeout (number/promise)
withCredentials (boolean)
responseType (string)
15.3 Response Object
The response object that Angular passes to the then() method contains four properties:
data (string/object)
status (number)
headers (function)
config (object)
0 notes
Text
AngularJS Notes (14 - 2)
Study Notes of “The Complete Book on AngularJS”
Chapter 14: Service
14.3 Options for Creating Services
14.3.1 factory( )
The factory( ) function takes two arguments:
name (string): the name of the service instance we want to register.
getFn (function): the function runs when Angular creates the service.
angular.module('myApp') .factory('githubService', ['$http', function($http) { return {getUserEvents: function(username) { // ... } }; }]);
14.3.2 service( )
Enables us to register a constructor function for our service object.
The service( ) function takes two arguments:
name (string): the name of the service instance we want to register.
constructor (function): the constructor function that we’ll call to instantiate the instance.
var Person = function($http) { this.getName = function( ) {return...}; }; angular.service('personService', Person);
14.3.3 provider( )
A provider is an object with a $get( ) method. The $injector calls the $get method to create a new instance of the service.
At the root of all the methods for creating a service is the provider method. The provider( ) method is responsible for registering services in the $providerCache.
Technically, the factory( ) function is shorthand for creating a service through the provider( ) method wherein we assume that the $get() function is the function passed in.
.factory('myService', function() { return {'username': 'auser'} })
is equivalent to:
.provider('myService', { $get: function() { return {'username': 'auser'} } });
Why would we ever need to use the .provider() method?
By using the .provider() method, we have more flexibility when using our service in more than one app. If we want to be able to configure the service in the config() function, we must use provider() to define our service.
angular.module('myApp', []) .provider('githubService', function($http) { var githubUrl = 'https://github.com' setGithubUrl: function(url) { if (url) { githubUrl = url } } });
angular.module('myApp', []) .config(function(githubServiceProvider) { githubServiceProvider.setGithubUrl("[email protected]"); })
The provider( ) function takes two arguments:
name (string): a string that we use as the key in the providerCache. This argument makes the name + Provider available as the provider for the service.
aProvider (object/function/array):
The most raw method of creating a service is by using the provider() API directly. (must return an object that has the $get() function defined). We can instantiate the service with the injector.
14.3.4 constant( )
Register an existing value as a service that we can later inject into other parts of our app as a service.
The constant( ) function takes two arguments:
name (string): the name with which to register the content.
value (content value): the value to register as the constant
.constant('apiKey', '123123123')
14.3.5 value( )
If the return value of the $get method in our service is a constant, we don’t need to define a full-blown service with a more complex method. We can simply use the value( ) function to register the service.
The value() method accepts two arguments:
name (string): the name with which we want to register the value.
value (value): the injectable instance.
.value('apiKey','123123123');
14.3.6 When to Use Value or Constant
The major difference between the value( ) method and the constant( ) method is that you can inject a constant into a config function, whereas you cannot inject a value.
14.3.7 decorator( )
The $provide service gives us a way to intercept the service instance creation. Decorating our services enables us to extend services or replace them with something else entirely.
Decorators:
provide decorations for our own services.
intercept, interrupt, and even replace functionality in the core Angular services.
The decorator() function takes two arguments:
name (string): the name of the service to decorate.
decoratorFn (function): the function that we’ll invoke at the time of service instantiation. The function is called with injector.invoke, which allows us to inject services into it.
In order to decorate a service, we need to inject the $delegate, which is the original service instance that we can decorate.
var githubDecorator = function($delegate, $log) { var events = function(path) { var startedAt = new Date(); var events = $delegate.events(path); var result = $delegate.locate( ); events.always(function() { $log.info("Fetching events" + " took " + (new Date() - startedAt) + "ms"); }); return result; } return { events: events}; };
angular.module('myApp') .config(function($provide) { $provide.decorator('githubService', githubDecorator); });
0 notes
Text
AngularJS Notes (14 - 1)
Study Notes of “The Complete Book on AngularJS”
Chapter 14: Service
Services provide a method for us to keep data around for the lifetime of the app and communicate across controllers in a consistent manner.
Services are singleton objects that are instantiated only once per app (by the $injector) and lazy- loaded (created only when necessary). They provide an interface to keep together those methods that relate to a specific function.
All we need to do is register the service. Once a service is registered, the Angular compiler can reference it and load it as a dependency for runtime use.
14.1 Registering a Service
The most common and flexible way to create a service uses the angular.module API factory:
angular.module('myApp.services', []) .factory('githubService', function() { var serviceInstance = {}; return serviceInstance; });
This service factory function is responsible for generating a single object or function that becomes this service, which will exist for the lifetime of the app. When our Angular app loads the service, the service will execute this function and hold on to the returned value as the singleton service object.
To expose a method on our service, we can place it as an attribute on the service object.
14.2 Using Services
To use a service, we need to identify it as a dependency for the component where we’re using it.
0 notes
Text
AngularJS Notes (13)
Study Notes of “The Complete Book on AngularJS”
Chapter 13: Dependency Injection
Dependency injection is a design pattern that allows for the removal of hard-coded dependencies, thus making it possible to remove or change them at run time.
Angular uses the $injector for managing lookups and instantiation of dependencies. When any of our modules boot up at run time, the injector is responsible for actually instantiating the instance of the object and passing in any of its required dependencies.
In every Angular app, the $injector has been at work, whether we know it or not. When we write a controller without the [] bracket notation or through explicitly setting them, the $injector will infer the dependencies based on the name of the arguments.
13.1 Annotation by Inference
Angular assumes that the function parameter names are the names of the dependencies, if not otherwise specified.
13.2 Explicit Annotation
The injection process uses the $inject property to annotation the function. The $inject property of a function is an array of service names to inject as dependencies.
aControllerFactory.$inject = ['$scope', 'greeter'];
13.3 Inline Annotation
Inline annotation allows us to pass an array of arguments instead of a function when defining an Angular object. The elements inside this array are the list of injectable dependencies as strings, the last argument being the function definition of the object.
angular.module('myApp') .controller('MyController', ['$scope', 'greeter', function($scope, greeter) {...}]);
13.4 $injector API
1. annotate(function or array): returns an array of service names that are to be injected into the function when instantiated.
2. get(name): returns an instance of the service.
3. has(name): returns true if the injector knows that a service exists in its registry and false if it does not.
4. instantiate(Type, locals): creates a new instance of the JavaScript type.
5. invoke(fn, self, locals): invokes the method and adds the method arguments from the $injector.
13.5 ngMin
ngMin is a pre-minifier for Angular apps. It walks through our Angular apps and sets up dependency injection for us.
13.5.1 Installation
$ npm install -g ngmin
13.5.2 Using ngMin
$ ngmin input.js output.js OR $ ngmin < input.js > output.js
13.5.3 How It Works
At its core, ngMin uses an Abstract Syntax Tree (AST) as it walks through the JavaScript source. With the help of astral, an AST tooling framework, it rebuilds the source with the necessary annotations and then dumps the updated source using escodegen.
0 notes
Text
AngularJS Notes (12 - 2)
Study Notes of “The Complete Book on AngularJS”
Chapter 12: Multiple Views and Routing
12.4 $location Service
AngularJS provides a service that parses the URL in the address bar and gives you access to the route of the current path of your applications. We’ll use the $location service whenever we need to provide a redirect internal to our app
1. path( )
$location.path(); // returns the current path $location.path('/'); // change the path to the '/' route
2. replace( )
Redirect completely without giving the user the ability to return using the back button.
$location.path('/home').replace();
3. absUrl( )
Get full URL representation with all segments encoded.
4. hash( )
Get or change the hash fragment in the URL.
$location.hash(); $location.hash('movies');
5. host( ) / port( ) / protocol( )
Get the host / port / protocol of the current URL.
6. search( )
Get or modify the search part of the current URL.
$location.search(); $location.search({name: 'Ari', username: 'auser'}); $location.search('name=Ari&username=auser');
7. url( )
Get or change the URL of the current page.
$location.url(); // String of the url
$location.url("/home?name=Ari#hashthing")
12.5 Routing Modes
The routing mode refers specifically to the format of the URL in the browser address bar. The default behavior of the $location service is to route using the hashbang mode.
Hashbang Mode
A hashbang URL looks like: http://yoursite.com/#!/inbox/all
HTML5 Mode
This mode makes your URLs look like regular URLs: http://yoursite.com/inbox/all
When writing links inside of our Angular app in html5mode, we’ll never want to use relative links. You can set the base URL of your app using the <base> tag in the HEAD section of the HTML document: <base href="/base/url" />
12.5.1 Routing Events
The $route service fires events at different stages of the routing flow. It’s possible to set up event listeners for these different routing events and react.(Particularly useful for detecting when users are logged in and authenticated.)
To set up an event listener to listen for routing events, use the $rootScope.
1. $routeChangeStart
Angular broadcasts $routeChangeStart before the route changes. This step is where the route services begin to resolve all of the dependencies necessary for the route change to happen and where templates and the resolve keys are resolved.
angular.module('myApp', []) .run(['$rootScope', '$location', function($rootScope, $location) { $rootScope.$on('$routeChangeStart', function(evt, next, current) {}) }])
2. $routeChangeSuccess
Angular broadcasts the $routeChangeSuccess event after the route dependencies have been resolved.
$rootScope.$on('$routeChangeSuccess', function(evt, next, previous) {...}
3. $routeChangeError
Angular broadcasts the $routeChangeError event if any of the promises are rejected or fail.
$rootScope.$on('$routeChangeError', function(current, previous, rejection) {...}
4. $routeUpdate
Angular broadcasts the $routeUpdate event if the reloadOnSearch property has been set to false and we’re reusing the same instance of a controller.
12.5.2 Note About Indexing
To support web crawlers that run through the app, we need to add a meta tag in the head. This meta tag causes the crawler to request links with an empty escaped fragment parameter so that the back end will serve back snippets of HTML.
<meta name="fragment" content="!" />
12.6 Other Advanced Routing Topics
12.6.1 Page Reloading
The $location service does not reload the entire page; it simply changes the URL. If we need to cause a full page reload, we have to set the location using the $window service:
$window.location.href = "/reload/page";
12.6.2 Async Location Changes
If we need to use the $location service outside of the scope life cycle, we have to use the $apply function to propagate the changes throughout the app.
0 notes
Text
AngularJS Notes (12 - 1)
Study Notes of “The Complete Book on AngularJS”
Chapter 12: Multiple Views and Routing
We’ll break partial templates into views to be composed inside of a layout template. AngularJS allows us to do that by declaring routes on the $routeProvider, a provider of the $route service.
12.1 Installation
Download it from code.angularjs.org or use Bower.
Reference angular-route in our HTML.
<script src="js/vendor/angular.js"></script> <script src="js/vendor/angular-route.js"></script>
Reference the ngRoute module as a dependency in our app module.
ng-book angular.module('myApp', ['ngRoute']);
12.2 Layout Template
Using the ng-view directive + the router, we can specify exactly where in the DOM we want to place the rendered template of the current route.
<div class="content"> <div ng-view></div> </div>
ng-view: a special directive that’s included with the ngRoute module. Its specific responsibility is to stand as a placeholder for $route view content. It creates its own scope and nests the template inside of it.
12.3 Routes
The when (path, route) method:
The first parameter is the route path, which is matched against the $location.path, the path of the current URL.
The second parameter is the configuration object, which determines exactly what to do if the route in the first parameter is matched. The configuration object properties that we can set are controller, template, templateURL, resolve, redirectTo, and reloadOnSearch.
and the otherwise method.
angular.module('myApp', [])
.config(['$routeProvider', function($routeProvider) { $routeProvider .when('/dashboard', templateUrl: 'views/dashboard.html', controller: 'DashboardController', resolve: { user: function(SessionService) { return SessionService.getCurrentUser(); } } }) .otherwise({ redirectTo: '/' }); }]);
When the browser loads the Angular app, it will default to the URL set as the default route. Unless we load the browser with a different URL, the default is the ‘/’ route.
1. controller
The controller given will be associated with the new scope of the route.
2. template
Angular will render the HTML template in the ng-view DOM element.
3. templateUrl
The app will attempt to fetch the view using XHR (utilizing the $templateCache).
4. resolve
Angular will inject the elements of the map into the controller. (If these dependencies are promises, they will be resolved and set as a value before the controller is loaded and before the $routeChangeSuccess event is fired.)
The map object can be a:
key: the string name of a dependency that will be injected into the controller.
factory: can either be a string of the name of a service, a function whose result is injected into the controller, or a promise that is to be resolved.
5. redirectTo
Trigger a route-change request.
6. reloadOnSearch
If the reloadOnSearch option is set to true (by default), then reload the route when $location.search() is changed.
$routeParams
If we start a route param with a colon (:), AngularJS will parse it out and pass it into the $routeParams.
.when('/inbox/:name', {...}
0 notes
Text
AngularJS Notes (11)
Study Notes of “The Complete Book on AngularJS”
Chapter 11: Angular Module loading
11.1 Configuration
Angular executes blocks of configuration during the provider registration and configuration phases in the bootstrapping of the module. This phase is the only part of the Angular flow that may be modified before the app starts up.
angular.module('myApp', []) .config(function($provide) { ...});
.factory, .directive... are syntactic sugar around the .config() function.
There are only a few types of objects that we can inject into the .config() function: providers and constants. We can only inject custom services that are built with the provider() syntax and cannot inject other services.
These .config() blocks are how we’ll custom configure our own services, such as setting API keys and custom URLs.
The config() function takes a single argument: configFunction (function), the function that Angular executes on module load.
angular.module('myApp', []) .config(function($routeProvider) { $routeProvider.when('/', { controller: 'WelcomeController', template: 'views/welcome.html' }); }) .config(function(ConnectionProvider) { ConnectionProvider.setApiKey('SOME_API_KEY'); })
11.2 Run Blocks
Unlike the configuration blocks, run blocks are executed after the injector is created and are the first methods that are executed in any Angular app.
Run blocks are the closest thing in Angular to the main method.
Typically, these run blocks are places where we’ll set up event listeners that should happen at the global scale of the app.
The run() function takes a single argument: initializeFn (function). Angular executes this function after it creates the injector.
angular.module('myApp', []) .run(function($rootScope, AuthService) {...});
0 notes
Text
AngularJS Notes (10 - 4)
Study Notes of “The Complete Book on AngularJS”
Chapter 10: Directives Explained
10.5 ngModel
It gives us a deeper API for handling data from within a controller.
In order to gain access to this ngModelController, we must use the require option.
In order to set the view value of a scope, we must call the API function ngModel.$setViewValue(), which takes a single argument: value (string).
Using the $setViewValue() method is a good idea when creating a custom directive that listens for custom events.
require: '?ngModel', link: function(scope, ele, attrs, ngModel) { if (!ngModel) return; $(function() { ele.datepicker({ onSelect: function(date) { scope.$apply(function() { ngModel.$setViewValue(date); }); } }) });
10.5.1 Custom Rendering
It’s possible to define how the view actually gets rendered by defining the $render method on the controller. This method will be applied after the $parser pipeline has completed. (disruptive to the Angular Way)
ngModel.$render = function() { element.html(ngModel.$viewValue() || 'None'); }
10.5.2 Properties
ngModelController has a few properties available that we can examine and even modify to change our view:
$viewValue: holds onto the actual string value that’s updated in the view. $modelValue: the value held by the model.
$parsers: an array of functions that get executed in a pipeline to sanitize and modify the value.
$formatters: an array of functions that get executed as a pipeline when the model value changes to format and convert values to display within the bound control.
$viewChangeListeners: an array of functions to execute when the view value has changed. $error
$error: holds onto the object of errors where the key is the failed validation name and the value is the actual error message.
$pristine / $dirty: a boolean that tells us whether or not the user has made any changes to the control yet.
$valid / $invalid: tells us if there is error on the control.
0 notes
Text
AngularJS Notes (10 - 3)
Study Notes of “The Complete Book on AngularJS”
Chapter 10: Directives Explained
10.4 AngularJS Life Cycle
There are two main phases that take place: compile + link
10.4.1 Compile Phase
During the compile phase, Angular slurps up our initial HTML page and begins processing the directives we declared.
Once a directive and its child templates have been walked or compiled, a function is returned for the compiled template known as the template function. (Each directive returns its own template function. The top-level directive that started the chain returns the combined template function of all its children. )
Built-in directives, such as ng-repeat, manipulate the DOM before it has been bound to any scope data.
Once we have compiled a complete representation of a single directive, we momentarily have access to it via the compile function. This compile function returns the template function, which includes the entire parsed tree.
Finally, the template function is passed to the link function.
Compile (object|function)
The compile option and the link option are mutually exclusive.
Oftentimes, when we set the compile function, we’re interested in manipulating the DOM before we place the directive on it with live data. Here, it is safe to manipulate HTML, add and remove elements, etc.
The template instance and link instance may be different objects if the template has been cloned. Thus, we can only do DOM transformations that are safe to do to all cloned DOM nodes within the compile function. Don’t do DOM listener registration: That should be done in the linking function.
The compile function deals with transforming the template DOM.
The link function deals with linking scope to the DOM.
10.4.2 Link
We use the link option to create a directive that manipulates the DOM.
The following tow definition of the directive are functionally equal:
angular.module('myApp' []) .directive('myDirective', function() { return { pre: function(tElement, tAttrs, transclude) { }, post: function(scope, iElement, iAttrs, controller) { } } });
angular.module('myApp' []) .directive('myDirective', function() { return { link: function(scope, ele, attrs) { return { pre: function(tElement, tAttrs, transclude) { }, post: function(scope, iElement, iAttrs, controller) { } } } });
Link functions is invoked after the compiled template has been linked to the scope, and is therefore responsible for setting up event listeners, watching for data changes, and manipulating the live DOM.
The link function has the following signature:
require 'SomeController', link: function (scope, element, attrs, SomeController) { }
scope: The scope to be used by the directive for registering watches from within the directive.
iElement: The element where the directive is to be used. We should only manipulate children of this element in the postLink function.
iAttrs: A normalized list of attributes declared on this element and are shared between all directive linking functions.
controller: Points to the controller that’s defined by the require option.
0 notes
Text
AngularJS Notes (10 - 2)
Study Notes of “The Complete Book on AngularJS”
Chapter 10: Directives Explained
10.2 Directive Scope
A special object, known as the $rootScope, is initially created when we declare the ng-app directive in the DOM.
10.2.1 Scope Option (boolean | object)
When scope is set to true, a new scope object is created that prototypically inherits from its parent scope.
10.2.2 Isolate Scope
The main use case for such directives is reusable widgets that can be shared and used in unex- pected contexts without polluting the scope around them or having their internal scope corrupted inadvertently.
To create a directive with isolate scope we’ll need to set the scope property of the directive to an empty object, {}. Once we’ve done that, no outer scope is available in the template of the directive.
10.3 Binding
@ (one-way binding) allows a value defined on the directive attribute to be passed to the directive's isolate scope. The value could be a simple string value (myattr="hello") or it could be an AngularJS interpolated string with embedded expressions (myattr="my_{{helloText}}"). You can think of it as "one-way" communication from the parent scope into the child directive.
= (two-way binding) sets up a two-way binding expression between the directive's isolate scope and the parent scope. Changes in the child scope and propagated to the parent and vice-versa. Think of = as a combination of @ and &.
& (function binding) allows the directive's isolate scope to pass values into the parent scope for evaluation in the expression defined in the attribute. Allows the directive to call some parentScope function and pass in some value from the directive.
10.3.1 Transclude
Transclusion makes it easy to allow users of our directive to customize all these aspects at once by allowing them to provide their own HTML template that has its own state and behavior.
reusable directive
customize
This code tells the Angular compiler that where it finds the ng-transclude directive is where it should place the content that it has captured from inside the DOM element.
If we use transclude, watching for model property changes from within the controller of a directive will not work properly. That is why best practice always recommends using the $watch service from within the link function.
10.3.2 controller (string|function)
Arguments that we can pass into a controller are:
$scope: The current scope associated with the directive element.
$element: The current element directive element.
$attrs: The attributes object for the current element. For instance, the following element.
$transclude: A transclude linking function pre-bound to the correct transclusion scope.
ng-bookThis transclude linking function is the function that will run to actually create a clone of the element and manipulate the DOM.
controller: function($scope, $element, $transclude) { $transclude(function(clone) { var a = angular.element('<a>'); a.attr('href', clone.text()); a.text(clone.text()); $element.append(a); }); }
Directive’s controller vs. directive’s link function
The main use case for a controller is when we want to provide reusable behavior between directives. As the link function is only available inside the current directive, any behavior defined within is not shareable.
The link function provides isolation between directives, while the controller defines shareable behavior.
Using the controller option is good when we want to expose an API to other directives; otherwise, we can rely on link to provide us local functionality for the directive element. It’s better to use link when we use scope.$watch() or when we’re doing any interaction with the live scope of the DOM.
10.3.3 ControllerAs (string)
The controllerAs option enables us to set a controller alias, thus allowing us to publish our controller under this name and giving the scope access to the controllerAs name. This step allows us to reference the controller from inside the view and even allows us to not need to inject $scope.
10.3.4 require (string|array)
require is used to inject the controller of the required directive as the fourth parameter of the current directive’s linking function.
prefix:
?: If the required controller is not found on the directive provided, pass null to the 4th argument of the link function.
ˆ: The directive will look upwards on its parent chain for the controller in the require option.
?ˆ: Optionally require the directive and look up the parent chain for the directive.
No prefix: we tell the directive to locate the required controller on the named directive provided and throw an error if no controller (or directive by that name) is found.
0 notes