{"id":16739380,"url":"https://github.com/zafarali/learning-angular","last_synced_at":"2026-01-26T22:55:16.075Z","repository":{"id":78568202,"uuid":"20888203","full_name":"zafarali/learning-angular","owner":"zafarali","description":"A repo containing all code used to learn AngularJS, Scroll down to README for the tutorial.","archived":false,"fork":false,"pushed_at":"2018-02-07T15:28:30.000Z","size":69,"stargazers_count":593,"open_issues_count":0,"forks_count":55,"subscribers_count":39,"default_branch":"master","last_synced_at":"2025-01-22T11:47:41.441Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"HTML","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/zafarali.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2014-06-16T14:38:48.000Z","updated_at":"2024-11-24T04:35:13.000Z","dependencies_parsed_at":"2023-03-12T04:38:54.575Z","dependency_job_id":null,"html_url":"https://github.com/zafarali/learning-angular","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zafarali%2Flearning-angular","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zafarali%2Flearning-angular/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zafarali%2Flearning-angular/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zafarali%2Flearning-angular/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/zafarali","download_url":"https://codeload.github.com/zafarali/learning-angular/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243801611,"owners_count":20350106,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-13T00:50:39.768Z","updated_at":"2026-01-26T22:55:11.052Z","avatar_url":"https://github.com/zafarali.png","language":"HTML","funding_links":[],"categories":[],"sub_categories":[],"readme":"Learning AngularJS\n================\nUpdates\n\n**Note: about Angular 2: Angular 2 has many drastic changes, I might get to an Angular 2 tutorial over the summer!**\n\n***I noticed how untidy the main folder has become, however I am not going to move any of the files anywhere due to the fact that all the links are now fixed in this README. If there is another tutorial that comes up then I will create a separate folder with the code and README for that curriculum - *Thanks for visiting!* ***\n\n![ng!](https://angularjs.org/img/AngularJS-large.png)\n\nSo I've been meaning to learn AngularJS for some time now and I've watched a few videos here and there but kept on dropping and never building anything concrete. This repo will help me track my progress through two curriculums I've found on thinkster.io and codeschool.com:  \n\n1. [A Better Way to Learn AngularJS](http://www.thinkster.io/angularjs/GtaQ0oMGIl/a-better-way-to-learn-angularjs)  \n2. [Shaping up with AngularJS](http://campus.codeschool.com/courses/shaping-up-with-angular-js/intro)  \n\nThis repository will also include code from other sources which I will cite in the comments and below when I find them. There are also basic code example as alternative to demos shown in the videos so that we can see more than one example to be able to accurately wrap ones head around.\n\nThis README will also track some codes, gotchas, comments and other shenanigans to help others like me learning AngularJS for the first/second/third time. Hope this helps!\n\n##### Prerequisites\n- [ ] HTML\n- [ ] CSS\n- [ ] JS (OOPs, Prototyping, functions, events, error handling)\n- [ ] Idea of the Model-View-Controller technique\n- [ ] The Document Object Model \n\n##### Requirements\n- [ ] Web browser\n- [ ] Acccess to the O'Rielly AngularJS Book. If you are a student you can access it [here](http://proquest.safaribooksonline.com/book/programming/javascript/9781449355852/firstchapter) using your university VPN. [*AngularJS by Brad Green and Shyam Seshadri (O’Reilly). Copyright 2013 Brad Green and Shyam Seshadri, 978-1-449-34485-6.*]\n\n### 00-Concepts\nAngularJS relies heavily on the MVC approach:\n- a **Model** which contains the data shown to the user in the view and with which the user interacts. (think of it as the place where we store the data)\n- a **View** this is what the user sees. (the user interface or the DOM)\n- the **controller** which contains all the logic.\n\nThere are some *buzzwords* used in AngularJS:\n- **Data Binding** is the sync of data between the model and the view \n- **Two way Data Binding** is a feature of angular that says that everything in the document is live. Whenever the input changes the expression is automatically recacluated and the DOM is updated as well.\n- **Scope** ~~this is where the variables and data (known as model) are stored, think of it as the traditional *scope* that allows all other components to access the data in the model.~~ So someone pointed out that this definition was vague. After some more reading, it turns out that the Scope is where your application will execute expressions, scopes are nested and the root scope usually doesn't contain anything in it. Without trying to complicate our lift off with definitions, think of the scope *of a controller* as the place where our data is stored which 'forms the glue between the controller and the view'.  \n- **Templates** all HTML files with angular code are known as templates because angular must fill in expressions and other gadgematics.\n- **Directives** apply special behaviour to HTML elements. For example the `ng-app` attribute in our [00-concepts.html](https://github.com/zafarali/learning-angular/blob/master/00-0-concepts.html) file is linked to a directive that automatically initializes the application. When we define `ng-model` attributes to our `\u003cinput\u003e` element, we create a directive that stores and updates the value from the `\u003cinput\u003e` field to the *scope*.\n- **filters** format the value of an expression for display to the user. Filters are very useful and in our [00-concepts.html](https://github.com/zafarali/learning-angular/blob/master/00-0-concepts.html) file we use `currency` to format the output of the expression to resemble a bill or currency.\n\nThe image summarizes [00-1-concepts.html](https://github.com/zafarali/learning-angular/blob/master/00-1-concepts.html)  \n![Interaction between Controllers-Scope/Model-View](https://docs.angularjs.org/img/guide/concepts-databinding2.png)  *image from [AngularJs Docs](https://docs.angularjs.org/guide/concepts)*\n\n- **Services** contain all the 'independent logic', which is other words is a way to supply and manipulate data to our application. We use services to allow us to reuse it in other parts of the application. For example in [00-1-concepts.html](https://github.com/zafarali/learning-angular/blob/master/00-1-concepts.html) all the logic was stored within `InvoiceController`. In [00-2-concepts.html](https://github.com/zafarali/learning-angular/blob/master/00-2-concepts.html) we will refactor the code to move the conversion logic into a service in another module.\n\n- **Dependency Injection** In [00-2-concepts.html](https://github.com/zafarali/learning-angular/blob/master/00-2-concepts.html) we see that `ng-app` defines `invoice-srv-demo` as the main module to use in application. In the defintiion of this module we state that `finance` is a dependency of the main module. We also define the constructor for the controller after passing in the dependency `currencyConverter` from the finance module. This is known as *dependency injection*\n\n### 00-Spin\n#### The Dot.\nFound this gotcha thanks to [this video](http://www.thinkster.io/angularjs/axAQatdKIq/angularjs-the-dot).\n```html\n\t\u003cscript\u003e\n\t\tfunction FirstCtrl($scope) {}\n\t\tfunction SecondCtrl($scope) {} \n\t\u003c/script\u003e\n\t\u003cdiv ng-app=\"\"\u003e\n\t\t\u003cdiv ng-controller=\"myCtrl\"\u003e\n\t\t\t\u003cinput type=\"text\" ng-model=\"message\"\u003e\n\t\t\t\u003cbr /\u003e\u003ch1\u003e\u003cb\u003e{{message}}\u003c/b\u003e\u003c/h1\u003e\n\t\t\u003c/div\u003e\n\t\t\u003cdiv ng-controller=\"yourCtrl\"\u003e\n\t\t\t\u003cinput type=\"text\" ng-model=\"message\"\u003e\n\t\t\t\u003cbr /\u003e\u003ch1\u003e\u003cb\u003e{{message}}\u003c/b\u003e\u003c/h1\u003e\n\t\t\u003c/div\u003e\n\t\u003c/div\u003e\n```\nIf we set up our code as above, *scope inheritence* is broken. Each new `ng-model` that we set up for the `message` is creating a new instance of message which means there is no longer communication between the two `message`s. To rectify this we place a `data` model on the `$scope` which has the `message` property. I like to think of this as each controller getting its own scope because rectifying the code as shown below also doesn't fix the issue and no data is shared between the two controllers.\n```html\n\t\u003c!--Script remains the same--\u003e\n\t\u003cdiv ng-app=\"\"\u003e\n\t\t\u003cdiv ng-controller=\"myCtrl\"\u003e\n\t\t\t\u003cinput type=\"text\" ng-model=\"data.message\"\u003e\n\t\t\t\u003cbr /\u003e\u003ch1\u003e\u003cb\u003e{{data.message}}\u003c/b\u003e\u003c/h1\u003e\n\t\t\u003c/div\u003e\n\t\t\u003cdiv ng-controller=\"yourCtrl\"\u003e\n\t\t\t\u003cinput type=\"text\" ng-model=\"data.message\"\u003e\n\t\t\t\u003cbr /\u003e\u003ch1\u003e\u003cb\u003e{{data.message}}\u003c/b\u003e\u003c/h1\u003e\n\t\t\u003c/div\u003e\n\t\u003c/div\u003e\n```\nHowever editing the code in a way (below) such that there is a scope set up for the entire application will ensure that the scope can sync data between the controllers.\n```html\n\u003c!--Script remains the same, we initialize data.message with 'hi'--\u003e\n\t\u003cdiv ng-app=\"\" ng-init=\"data.message='hi'\"\u003e\n\t\t{{data.message}}\n\t\t\u003cdiv ng-controller=\"myCtrl\"\u003e\n\t\t\t\u003ch1\u003e{{2+2}}\u003c/h1\u003e\n\t\t\tType in a message: \u003cinput type=\"text\" ng-model=\"data.message\"\u003e\n\t\t\t\u003cbr /\u003e\u003ch1\u003e\u003cb\u003e{{data.message}}\u003c/b\u003e\u003c/h1\u003e\n\t\t\u003c/div\u003e\n\t\t\u003cdiv ng-controller=\"yourCtrl\"\u003e\n\t\t\tType in a message: \u003cinput type=\"text\" ng-model=\"data.message\"\u003e\n\t\t\t\u003cbr /\u003e\u003ch1\u003e\u003cb\u003e{{data.message}}\u003c/b\u003e\u003c/h1\u003e\n\t\t\u003c/div\u003e\n```\n*(this observation is indeed true, we need to have a parent to allow this kind of inheritence)*. We now look at a different way to do this.\n#### Data sharing between controllers\nThis can be done by creating a *factory* which will supply the data. We then bind the local `$scope`s to the `Data` factory where we can then sync data between the controllers. See [00-2-spin.html](https://github.com/zafarali/learning-angular/blob/master/00-2-spin.html).\n```javascript\nvar myApp = angular.module('myApp', []);\nmyApp.factory('Data', function(){return{message:\"this is important\"};});\nfunction myCtrl($scope,Data){$scope.data = Data;}\nfunction yourCtrl($scope,Data){$scope.data = Data;}\n```\n### Shopping Cart (01-1-shopping and 01-1-forms)\nThe [shopping cart](https://github.com/zafarali/learning-angular/blob/master/01-1-shopping.html) example demonstrates some of the other functionality of the AngularJS framework. You may have noticed that we have seen two ways to creating `controller`s:\n```javascript\n//method 1\nfunction Ctrl($scope) {};\n//method 2\nvar myApp = angular.module('myApp', []);\nmyApp.controller('Ctrl', function($scope){});\n```\nWe can compare the two using our shopping cart app in [this commit](https://github.com/zafarali/learning-angular/commit/ce54e0d417f80a0087035b62e92a6f8030ccd4c0#diff-1d019a5313eee180347d30c7801153a5). Method 2 ensures that we keep our controllers out of the global namespace using the module we defined.  \nThe docs page regarding [forms](https://docs.angularjs.org/guide/forms) we find a whole load of neat tricks and tips that are demonstrated in [01-01-forms.html](https://github.com/zafarali/learning-angular/blob/master/01-1-forms.html). The page also demonstrates the abilities of `ng-show`, `ng-hide`, and validation techniques that AngularJS provides.\n### 02-Filters\n#### Custom filters\nThere's only syntax to learn here, watch this [video](http://www.thinkster.io/angularjs/EnA7rkqH82/angularjs-filters) and see the dummy code I [typed](https://github.com/zafarali/learning-angular/blob/master/02-1-filters.html) up. Another example is shown below using extra arguments that can be used as `text|decimal2binary:true`:\n```javascript\n//converts decimal to binary string\napp.filter('decimal2binary', function(){\n\tfunction convert(num,bool){\n\t    if(bool) { console.log('You specified true'); }\n        return parseInt(num,10).toString(2);\n\t}\n\treturn function(input, bool){\n\t\treturn convert(input, bool);\n\t}\n});\n```\n#### Searching and filters\nWe can see an implementation of the search technique in [02-2-filters.html](https://github.com/zafarali/learning-angular/blob/master/02-2-filters.html). Some other built-in AngularJS filters are summarized below:\n- `limitTo` will limit the number of results shown\n- `orderBy` takes a string and will order the results using the property it maps to\n- `lowercase` and `uppercase` turn the results to lower and upper case (these are best applied to the data binding as shown below)\n- `date`, `currency` format our data and are self explanatory\n- `number` takes a integer and rounds off the data to that decimal place. (eg: 0 would round off to 0dp)\n```html\n\u003cspan ng-repeat=\"element in list | filter: search | orderBy: 'lastname' | limitTo: 4\"\u003e\n{{element.lastname | uppercase}}, {{element.firstname | lowercase}}\n\u003c/span\u003e\n```\n### 03-Directives\n#### Custom elements\nDirectives are one of the  most impressive features AngularJS has to offer. In our first example we created a directive which is of `restrict`ion `'E'` which means that it is an element. Our directive is simple in that it just shows an image of a calculator created by the `\u003ccalculator\u003e` element. The [commit](https://github.com/zafarali/learning-angular/commit/fa0b6c1864501592e73ef3cea3e47e34c9763942) shows the code in detail.\n#### Custom Attributes and Classes\nThis [commit](https://github.com/zafarali/learning-angular/commit/403aad17fce1eb09e58b759dad63025db5166cf8) demonstrates a custom attribute that we built. Here, instead of setting `restrict:\"E\"` we set `restrict:\"A\"` and provide a `link` function which is executed whenever the attribute is attached. If we set `restrict:\"C\"` then the directive is executed whenever we have the class with that name [(see commit)](https://github.com/zafarali/learning-angular/commit/552ae91250175137f9e2b742883c7973c463dd48). We can also have directives in comments using `restrict:\"M\"` and the following:\n```html\n\u003c!--directive:myDirective--\u003e\n```\n#### Useful Directives\nDirectives default to `restrict:\"A\"`. The directive will also pass in the `scope` and `element` which we can use: as shown in [03-2-directives.html](https://github.com/zafarali/learning-angular/commit/d9e6515d2c8dd7b816907f98b9fa8f75472d4956). The directive also passes the `attrs` which is an object with all the attributes of the element. We can exploit this to make our code abstract when we want to add/remove classes. This is demonstrated in [this commit](https://github.com/zafarali/learning-angular/commit/a0636adf5790aeeb7d20489133bdc23d7d338578). We also see the use of `$apply()` to evaluate functions in [this example](https://github.com/zafarali/learning-angular/blob/master/03-3-directives.html).\n#### Directive Communication ([03-4-readinglist.html](https://github.com/zafarali/learning-angular/blob/master/03-4-readinglist.html))\nDirectives can communicate with each other as shown in the Reading List Example. Here we create a directive called `\u003cbook\u003e` and a couple of attributes that are dependent on the `book` directive. Each `\u003cbook\u003e` has a local scope as defined. `\u003cbook\u003e` also has an API which can control the local scope. Each attribute we define accesses the `\u003cbook\u003e` API to manipulate its properties. The properties can be viewed when we roll over it. A streamlined way (albeit without the romance,thriller etc. properties) is shown in [03-6-elements.html](https://github.com/zafarali/learning-angular/blob/master/03-6-elements.html).  \n- **Transclusion** We also have a `transclude` property which is demonstrated in [03-5-transclusion.html](https://github.com/zafarali/learning-angular/blob/master/03-5-transclusion.html) that allows whatever is inside our custom element to be placed inside it and not overwritten by the template. \n- *Nested elements* and how they communicate with each other are demonstrated in [03-7-nested.html](https://github.com/zafarali/learning-angular/blob/master/03-5-transclusion.html)\n\n#### Directive properties\nHere is a summary of the properties I see are most useful in directives:\n- `restrict:\"E\"||\"A\"||\"C\"||\"M\"` this declares how the directive behaves, as an element, attribute, class or comment respectively. We can use any combination of these.\n- `template:\"string\"` allows your directives to have a template.\n- `templateUrl:\"string\"` allows your directive to load a URL as a template.\n- `replace:bool` if true it will replace the current element and by default it is false and will append to the element.\n- `transclude` Lets you move the children of the directive into a place inside the template. We do this by specifiying `ng-transclude` attribute of the target location. In this example it targets the `\u003cspan\u003e` and not the other `\u003cdiv\u003e`s:\n```javascript\n//...\ntransclude:true,\ntemplate:\"\u003cdiv\u003e\u003cdiv\u003e\u003cspan ng-transclude\u003e\u003c/span\u003e\u003c/div\u003e\u003c/div\u003e\",\n//...\n```\n- `link:function()` executes when the directive sets up. It can be useful in setting `timeout`s, or binding `event`s to the element.\n- `controller:function()` allows you to set up scope properties and create an interface for other directives to interact with. This is also useful if you have functions in your directive that need to be executed by only your directive.\n- `controllerAs: 'String'` allows you to use the [Controller As]() syntax in your directives. *Note that things are bound to `this` and not to `scope`.* Refer to the notes from above for more details on the 'controllerAs' syntax.  \n-`scope:{}` allows you to create a new scope for the element rather than inherit from the parent.\n- `require:['^directives']` makes it mandatory for the current directive to be nested in the parent to ensure it functions correctly.  \nA quick gotcha to note, when you name your directive `datePicker` when declaring it, you can refer to it as `date-picker` in your HTML.\n\n#### Pre-link, Post-link and Compile\nFrom the readings it seems there are two important phases when an angular application is being created. \n1. The Loading of the Script (not so important for us right now)\n2. The **compile phase** is when the directives are registered, the templates are applied and the *compile* function is executed.\n3. The **link phase** occurs once the templates have been applied and the compile functions have been executed. In this phase the *link* functions are executed whenever the data in the view is updated.  \nThe main difference I see in them is that the *compile* function is executed once only during the compilation stage while the `link` function is executed once for each instance of the directive. At the moment I do not see an immediate use case for the compile function, however the book suggests that it is useful when you need to modify something in relation to all cases. Note the difference between the function defintions below, the `compile` function doesn't have access to the scope because it is not created yet.\n```javascript\nreturn {\n\trestrict:\"\",\n\trequire:\"\",\n\tcontroller:function(scope,element,attrs){},\n\tcompile: function(templateElement, templateAttrs, transclude){},\n\tlink: function(scope, instanceElement, instanceAttrs, controller){}\n}\n```\nIf we take a look at [03-8-compilevslink.html](https://github.com/zafarali/learning-angular/blob/master/03-8-compilevslink.html), we see the log executes the `controller` and the `compile`'s `pre` and `post` but not the link. Trying different combinations it seems that if you have a `compile`, you cannot have a `link` but you can get the effect of having a `compile` and `link` by setting a `pre` and `post` function to the `compile` function.  \n*UPDATE: I have just seen a [video](http://www.thinkster.io/angularjs/h02stsC3bY/angularjs-angular-element), it is indeed true that you cannot have a `link` function and a `compile` function. However, if we do choose to have a `compile` function, we can return (from the `compile` function) another function that will become the `link` function. Go see the website for a nice example on how this works.\n\n### 04-Scopes\nScopes can be nested. These nested scopes can either be *child scopes* (which inherits properties from its parents) or *isolate scopes* (which doesn't inherit anything). Everything that we try to evaluate for example `{{name}}` which is input via `ng-model='name'` will be held on the *scope*. Thus we can think of scopes as the link between the controllers/directives and the view.\n#### Isolate Scope\nWe can demonstrate a simple way to create an isolate scope for each directive we create as shown [04-0-scope.html](https://github.com/zafarali/learning-angular/blob/master/04-0-scope.html). When we define a directive, a property we can return is `scope`. This can be set to be `true`, `false`, or `{/*stuff inside*/}`. When we set to `false` (by default), it will use the existing scope in the directive. `true` will inherit the scope from the parent. `{}` will create an isolate scope for each directive. When you define an isolate scope there are *binding strategies* or methods of getting data into that scope. They are discussed below.\n##### @\nWe demonstrate two methods of using attributes to store data into the directives isolate scope in [04-1-scope.html](https://github.com/zafarali/learning-angular/blob/master/04-1-scope.html) \n##### =\nThe `@` operator will expect a string to bind the information we want to pass, however, the `=` will expect an object, this allows us to set up a two way binding between the parent scope and our directive scope. [04-2-scope.html](https://github.com/zafarali/learning-angular/blob/master/04-2-scope.html) demonstrates how updating the directive scope updates the parent. Note that in our attribute we are now passing objects and not strings.\n##### \u0026\nThe `\u0026` operator will evaluate an expression that you pass to it. So it seems that if you are passing values between the controller and the directive you need it to be in an object, and the object must map its properties to the function. This is demonstrated in [04-3-scope.html](https://github.com/zafarali/learning-angular/blob/master/04-3-scope.html).\n##### All together now!\n[04-4-review.html](https://github.com/zafarali/learning-angular/blob/master/04-4-review.html) encapsulates all the concepts we have discussed so far. Note that when we use `=`, we assume that the user is going to order from the same bookstore and thus we would like reflect the change in all other directives.\n#### Some Comments\n* We see that there is * **one** root scope*, and Angular will first look in the current scope before going up to the parent until it reaches the root scope. A demonstration follows:\n```html\n\u003cscript\u003e\nfunction MyParentCtrl($scope){\n\t$scope.name='John Doe'; \n\t$scope.home='Canada';\n}\nfunction MyChildCtrl($scope){\n\t$scope.name='Jane Doe';\n}\n\u003c/script\u003e\n\u003cdiv ng-app\u003e\n\u003cdig ng-controller=\"MyParentCtrl\"\u003e\nHello {{name}}! You are from {{home}}\n\u003cdiv ng-controller=\"MyChildCtrl\"\u003e\nHello {{name}}! You are from {{home}}\n\u003c/div\u003e\u003c/div\u003e\u003c/div\u003e\n```\nWhich will print out `Hello John Doe! You are from Canada\nHello Jane Doe! You are from Canada`. This demonstrates the point.\n* Broadcasting and Emmiting\n`$emit(name, args)` will allow an event to be executed in current and parent scopes. `$broadcast(name,args)` will allow an event to be executed in current and child scopes. This will be demonstrated in future pages but can be seen very nicely on this page [Scope Events Propagation](https://docs.angularjs.org/guide/scope#scope-events-propagation). [See bottom topic on this for more information](#Scope-Communcation)\n* `Controller as` Syntax allows us to refer to the Controller by an *alias*:\n```html\n\u003cscript\u003e function MyLongCtrlName(){\n\tthis.clickMe = function(){\n\t\talert(\"You clicked me!!\");\n\t}\n\n\tthis.name = \"Type your name here...\";\n}\u003c/script\u003e\n\u003cdiv ng-app ng-controller=\"MyLongCtrlName as ctrl1\"\u003e\n\u003cinput type=\"text\" ng-model=\"ctrl1.name\"\u003e\n{{ctrl1.name}} \n\u003cbutton ng-click=\"ctrl1.clickMe()\"\u003eClick this button\u003c/button\u003e\n\u003c/div\u003e\n```\nIt seems to add clarity to the code and in larger applications I think I will definietly be going to use it more often! \n\n### 05-Other Paradigms and tiny shenanigans\nSome alternative ways of thinking of Controllers and different ways of organizing angular applications is also provided on the thinkster.io page. I summarize them here very briefly:\n* Think of setting up a controller like this:\n```javascript\napp.controller(\"Ctrl\", function($scope){\n\tthis.hi = 'Hello';\n\tthis.sayHi = function(){\n\t\talert(this.hi);\n\t}\n\treturn $scope.Ctrl = this;\n});\n```\nWe can access this now using the following html:`\u003cdiv ng-click=\"Ctrl.sayHi()\"\u003eClick\u003c/div\u003e`. This serves to make the controller explicit and closely mimics the `Controller as` syntax above.\n* Organization. We can organize and initialize our controllers and directives like this. (however this doesn't work for filters)\n```javascript\nvar app = angular.module('myApp', []);\nvar myAppComponents = {};\n\nmyAppComponents.controllers = {};\nmyAppComponents.controllers.AppCtrl1 = function($scope){/*stuff here*/};\nmyAppComponents.controllers.AppCtrl2 = function($scope){/*stuff here*/};\n\nmyAppComponents.directives = {};\nmyAppComponents.directives.mydirective = function(){return {/*stuff here*/}};\n\napp.directive(myAppComponents.directives);\napp.controller(myAppComponents.controllers);\n```\n* When code bases become very large, we need modules. We have already seen that we have our main app in a module but we can actually create modules seperately. We have already shown this in [00-2-concepts.html](https://github.com/zafarali/learning-angular/blob/master/00-2-concepts.html) but just to drive home the point we reiterate using a directive and a factory in [05-0-modules.html](https://github.com/zafarali/learning-angular/blob/master/05-0-modules.html).\n\n* `$index`: We have already seen in past examples `$index` which holds the index of the current item in an `ng-repeat`. \n\n#### Mouse Events\nWe can use AngularJS listeners along with the `$event` object to do some interesting things. The directives are named in the following convention `ng-listener` where listener can be `click`, `dbl-click`, `mouseenter` etc...  Demonstrated in [05-1-event.html](https://github.com/zafarali/learning-angular/blob/master/05-1-event.html) is how we use `$event` to log the event. We can, by the same logic, pass the `$event` into a function that deals with the event in question.\n\n#### Console logging\nAngular has a built in method to log things to the console using `$log`. The [documentation](https://docs.angularjs.org/api/ng/service/$log) summarizes everything very simply and has a nice example that demonstrates it.\n\n#### Observing the model\n`$watch(toWatch, toDo, deepWatch)` is a function that allows you to observe changes in your model. We must note that executing this operation returns another function that if executed stops the watching. For example:\n```javascript\n$scope.$watch('username', function(){\n\tif($scope.username=='secret'){\n\t\tconsole.log('You typed in a secret name');\n\t}\n});\n```\nNow assume we have a `ng-model` input to allow the user to type in the `username`. When the value updates and evaluates to `secret` the message will be logged to the console.\n`$watch` can also watch functions to monitor their return function. The `deepWatch` parameter is a boolean. If set to true and an array of objects is passed into the `toWatch` parameter, each property of the object will be checked for changes.\n\n#### Angular Classes\nAngular automatically adds classes to some elements depending on how it's being used. Here are some use cases:\n* `ng-invalid`/`ng-valid` will be on an input element depending on if the text inside has passed validation or not\n* `ng-pristine`/`ng-dirty` - if the user hasn't interacted with an input element it will have the class of `ng-pristine` and if it has been interacted with it will be `ng-dirty`.\n* `ng-binding` is given to any element that has data binding on it.\n* `ng-scope` is given to any element with a new scope.\n* `ng-class` is an attribute of an element. We pass in an object with keys that are CSS class names and values are conditions. An example follows:\n```javascript\n\u003cdiv ng-class=\"{ showClass: whenThisIsTrue, showErrorClass: whenErrorIsTrue, neutralClass: !whenThisisTrue \u0026\u0026 !whenErrorIsTrue }\"\u003e...\u003c/div\u003e\n```\nMore information found [here](https://docs.angularjs.org/guide/css-styling)\n\n#### element()\nAngularJS implements jqLite which is a light version of jQuery. Thus if you are using jQuery on your page you can treat it as a jQuery element, if not we can just use the jqLite API to interact with it. We can see which jQuery methods that jqLite supports over at [the Angular Documentation](https://docs.angularjs.org/api/ng/function/angular.element#angular-s-jqlite).  \nA few quick tip:\n* Never use `element` in controllers as controllers only have logic for views.\n* Try to avoid using jQuery. If we must there is a [video here](https://www.youtube.com/watch?v=bk-CC61zMZk) which suggests that we keep jQuery manipulation within link functions of directives. *I haven't tried this myself yet*\n\n### 06-Template\nTemplates are an easy way of making your code very organized. [06-0-templateurl.html](https://github.com/zafarali/learning-angular/blob/master/06-0-templateurl.html) demonstrates how to link a partial file into the main view using the `templateUrl` property of a directive. Note that to use `templateUrl` we must have our files on a server. We can use `$templateCache` to load strings of html into the cache to mimic this effect if we do not have a seperate .html file. We then execute it using `app.run()` function.\nWe can retrieve what's on `$templateCache` using the `get` function and we can insert things into it using the `put` function as seen in the example at [06-1-templatecache.html](https://github.com/zafarali/learning-angular/blob/master/06-1-templatecache.html)\n\n### 07-Routing\n*This section requires you to have a server running, this can be easily executed by the bash command `php -S localhost:8080` on a Mac terminal*\n#### The `app.config` function\nIn the config phase of our application, there are objects known as providers available for us to use. They generate instances of services. This is not an important concept right now but basically the `.config` sets up what will be available to us in the controllers.\n#### `ng-view` and the `$routeProvider`\n`ng-view` is a directive that acts as a window that Angular can load views into. In the `config` function, we will inject `$routeProvider` whhere we can configure the different views and the controller associated with the view. The concept itself is difficult to grasp if you have never seen routing before but the syntax is relatively intuitive to pick up.  \nWe call the `.when(pg,{templateUrl:templatePage,controller:pageCtrl})` function on the `$routeProvider` object. The `pg` string is what the page url will look like. the `templatePage` and `pageCtrl` are strings which are matched to the page we want to load into the view and the controller associated with that object. This is demonstrated in [07-0-ngview.html](https://github.com/zafarali/learning-angular/blob/master/07-0-ngview.html). \nWe can chain multiple `.when()` functions together (which is the common methodology adpoted by most users). There is also an `.otherwise()` function which will be the default page incase a page is not found. This is demonstrated in [07-1-routing.html](https://github.com/zafarali/learning-angular/blob/master/07-1-routing.html) \n\n**NOTE: The information in the videos and in the book is slightly outdated. AngularJS no longer has `$routeProvider` built into it. We must inject the `ngRoute` module into our application and include a special link to the module. See 07-0-ngview.html for an example.**\n\n#### `$routeParams`\nThe `$routeParams` object when injected into a controller lets us access the parameters from the route. We define paramaters into our `$routeProvider` object as follows:\n```javascript\napp.config(['$routeProvider', function($routeProvider){\n\t$routeProvider.when('/path/:message',{\n\t\t\t\ttemplateUrl:myUrl,\n\t\t\t\tcontroller:myCtrl\n\t\t\t});\t\n}])\n```\nWe use the special syntax for `:message` to indicate that this is a parameter. Thus we can load multiple urls with `#/path/X` where X is the message we wish to pass in. Once this is configured we get this parameter in the controller by using `$routeParams.message`. We must note here that in both `:parameter` and `$routeParams.parameter`, the parameter must match to get the correct information. This is demonstrated in [07-2-routeParams.html](https://github.com/zafarali/learning-angular/blob/master/07-2-routeParams.html). Using this same ideology we can pass multiple parameters as follows: `.when('/:parameter1/:parameter2/:parameter3', ...)` and access it using `$routeParams.parameter1` etc.\n\n#### Dynamic Handling\nI call this dynamic handling (sounds cooler) but basically instead of just sending the user to a string we can actually use a function to return a dynamically created URL. The key here is to use the `redirectTo` property when passing the object into the `.when()` function.  \nImagine the scenario where you have a blog 'MyAmazingBlog' and you serve  `#/blog/postid` for a few years but  you want to start a new blog 'ExtraBlogStuff' and want to redirect people to the correct URL. We could write a function as follows:\n```javascript\napp.config(['$routeProvider', function($routeProvider){\n\t$routeProvider.when('/blog/:blogname/:blogpost',{\n\n\t\t//this returns the correct template for the blog, either MyAmazingBlog or ExtraBlogStuff, if not specified it will move onto //the next .when()\n\t\ttemplateUrl:function(routeParams){\n\t\treturn routeParams.blogname+'.html'; },\n\t\tcontroller:'BlogCtrl'\n\t})\n\t.when('/blog/:blogpost', {\n\t\t//here we direct our older linked users to the new blog\n\t\tredirectTo:function(routeParams){\n\t\treturn '/blog/MyAmazingBlog/'+routeParams.blogpost;\n\t});\n}]);\n```\nI hope this example clearly demonstrates a use case and how to for using the '$routeParams' and '$routeProvider' objects correctly.  \n*Note: The other parameters we can pass into the functions within route provider are as follows:*\n```javascript\nfunction(routeParams, path, search){\n\t//routeParams as we have seen above\n\t//path is the path url in full\n\t//search returns the queries after the path url\n\t//i.e. ?query=true\u0026message=what as a key:value object\n\treturn '/'; //we must return a string!\n}\n```\n#### Promises\nPromises are a way of executing a chain of functions. Some people say it avoids the bracket hell that occurs by passing in functions into functions. (Other benefits include: Error Handling in addition to clearer code)\nAngular comes with a promise library called `$q`. The key thing to remember is that we will deal with a `defer` object which we can pass in a sequence of functions to *(making some promises)* and then call the `resolve()` function to execute them.  \nIn [07-3-promises.html](https://github.com/zafarali/learning-angular/blob/master/07-3-promises.html) we demonstrate basic functionality of the promise objects and a slightly more complex version using the passing arguments. There is also a way to handle errors, this is demonstrated in the codeblock below:\n```javascript\ndefer.promise\n\t.then(function(name){\n\t\treturn name.split('').reverse().join('');\n\t})\n\t.then(function(reversedName){\n\t\t//do some more processing\n\t\treturn processedName;\n\t})\n\t.then(function(display){\n\t\tconsole.log(display);\n\t}, function(error){\n\t\t//handling the error in any of the prior steps\n\t});\n```\n\n#### Resolve property for $routeProvider\nIn addition to passing `templateUrl` and `controller` to the second object parameter of the `.when()` function, we can pass in `resolve` which is a list of promises that need to be resolved before the controller initiates. This allows us to load all necessary data before loading the view. Demonstrated by [this commit](https://github.com/zafarali/learning-angular/commit/2192e8cecc2a39386b9954ff165aaabc17771a79), I reiterate the experiment for clarity:  \n1. **URL: #/** This template will never load. This is because our promise is never resolved!  \n2. **URL: #/sup** This template loads instantaneously because we resolve the promise and then return it.  \n3. **URL: #/bye** This template loads after 3 seconds. This is because we use `$timeout` (which is a wrapper for `setTimeout()`) to `resolve()` the promise after 3 seconds.\n\nThis [video](http://www.thinkster.io/angularjs/6cmY50Dsyf/angularjs-resolve-conventions) demonstrates some conventions used when we use resolve properties in `$routeProvider`. Just to reiterate, all the functions we pass into the resolve properties are added to the Controllers as properties themselves. The video also points out that once the view loads, we can access the result of the resolve promises by using `$route.locals.nameOfResolvePromise`.\n\n#### Handling `$resolveChangeError`s\n*What happens if your promises don't resolve and instead throw errors?*  \nOur application would never load and nothing would show up no matter what we try to do. In this case we set up another default controller to handle this situation. A demonstration is at [07-5-ChangeError.html](https://github.com/zafarali/learning-angular/blob/master/07-5-ChangeError.html) make sure to read the comments to understand what is happening!  \nA [video](http://www.thinkster.io/angularjs/8u6fK7qWYv/angularjs-directive-for-route-handling) suggests that we create a directive to handle the `$routeChangeError`. I leave you to click over and read through how its done.\n\n#### `$location`\n`$location` is a wrapper around the `window.location` method/object. It provides some handy getters and setters and can use HTML5 methods when available or default to non-HTML5 methods. Since it is provided by AngularJS it is aware of when things change (We do not need to `watch()` it.)\nHere are some methods:  \n1. `absUrl()` returns the whole URL  including the paths  \n2. `host()` returns the host (i.e www.host.com)  \n3. `path()` returns the path the app is currently at.  \n4. `search()` allows us to get a key value pair for the queries passed in.  \n5. `url()` returns the path and the query parameters.  \n*Note that `path()`, `search()` and `url()` are also setters for the same property.*  \n\n- [ ] To Do The Route Life Cycle\n\n### Server Communication\nAnyone who has worked with servers and javascript would have come across AJAX and its method of fetching data from the server using `XMLHttpRequest()`. AngularJS makes it easy to deal with these kind of objects by wrapping them as example one shows.\n#### `$http`\n```javascript\n$http.get('api/user/', {params:{id:'5'}}\n\t\t).success(function(data,status,headers,config){\n\t\t\t//continue the application\n\t\t}).error(function(data,status,headers,config){\n\t\t\t//deal with the error here\n\t\t});\n```\nAs you can see this nicely wraps around a repetitive feature that we need often. \nAll return types of the above are promise objects. The `$http` object is called with a `config` object which follows this format:\n```javascript\nvar config = {\n\tmethod: \"GET\" || \"POST\", //...\n\turl: \"urlOfTarget\",\n\tparams: [{key1:'value1', key2:'value2'}], //this turns into ?key1=value1\u0026key2=value2\n\tdata: 'string'|| object, //..to be placed on the server\n\theaders: object, //to be defined later\n\tcache: boolean, //caching the data\n\ttimeout:int //how long to wait before expiring\n}\n```\nThere are some other config properties as well which I am refraining from discussing to keep things simple\nHere are some other (shorthand) methods that `$http` provides us with:  \n1. `$http.get(url, [config])`  \n2. `$http.post(url, data, [config])`  \n3. `$http.put(url, data, [config])`  \n4. `$http.delete(url, [config])`  \n5. `$http.jsonp(url, [config])`  \n6. `$http.head(url, [config])`  \nThe `$resource` object is a another method often used to interact with an API. This is explored in the next section.\n\n#### `$resource`\n*This has a dependancy ngResource*\nThe `$resource` is a wrapper for using an API.  We create a resource by calling `$resource(url, parameters, actions, options)`  \n```javascript\nvar UserProfile = $resource('/api/user/:userID', \n//get the id from a passed in string.\n{userID:'@id'},\n{\n\t//defining a custom action\n\tgetBalance: {method:'GET',params:{showBal:true}}\n});\n```\nManipulating the object is as easy as manipulating any user defined object:\n```javascript\nvar users = UserProfile.query(function(){\n\t//this does: \n\t//GET: /api/user/\n\t//the server returns:\n\t//[{id:1, name:'Jane'}, {id:2, name:'John'}];\n\n\t//we can access specific instaces of the cards as we refer to arrays. I.e users[0], users[1] ...\n\tvar user = users[0]\n\tuser.name = \"Doe\" //overrides the object property 'name' to Doe.\n\tuser.$save();\n\t//this does:\n\t//POST: /api/user/1 {id:1, name:'Doe'},\n\t//server returns the above.\n\n\tuser.$getBalance();\n\t//does a GET: /user/1?showBal=true\n\t\n});\n```\nWe can even create new instances as we do with regular objects:\n```javascript\nvar newUser = new UserProfile({name:\"James Bond\"});\nnewUser.$save();\n```\nThe functions/methods available to us without any further modification are:  \n1. `.get()` which does a GET request.  \n2. `.$save()` which does a POST request.  \n3. `.query()` which does a GET request and returns an array.  \n4. `.$remove()` which does a DELETE request.  \n5. `.$delete()` which does a DELETE request.  \nThe getters and the deleters, `.get()`, `.query()`, `.$remove()` and `.$delete()` can be passed a callback function with `(value,headers)` and the error callback is passed with `httpResponse` argument.   \nA full example of this would be `UserProfile.get({id:1}, function(data){/*do success stuff*/}, function(response){/*handle error*/})`.  \nThe setter `.$save()` is called with some data to be posted and has the same success/error callback pattern.   \nA full example of this would be:\n`Notes.$save({noteId:2, author:'Camillo'}, \"This is an amazing note wow\", successCallback, errorCallback)`\n\n1. **url** contains a parameterized version of the URL we are going to interact with. For example it can be: `http://www.myexample.com/data.json` or `http://www.myexample.com/api/user/:id`.  \n2. **parameters** sets default parameters that we are going to pass into the object. From what I see the most likely use case is with the `@` parameter. This will be elaborated later.  \n3. **options** Will be discussed later  \n4. **actions** will extend the functionality of the `$resource` object. This was demonstrated above but just for clarity here's another example: \n```javascript\napp.factory('Notes', ['$resource', function($resource){\n\treturn $resource('api/notes/:id', null, {'update':{method:'PUT'}\n\t});\n}]);\nNotes.update({id:'2'}, \"This is amazing!\");\n```\nWe can now call `Notes.update({id:id}, data);` after injecting the `Notes` factory into our controller.  \nThis makes our code easier to deal with by only dealing with objects and not with repeated instances of urls. We must note that `$resource` depends on `$http` which will be discussed shortly.\n\n##### Notes Regarding Cross Domain Requests\nYou may or may not know that Javascript cannot make AJAX calls to a domain thats not their own. i.e. your website (assuming you don't work for twitter) cannot ping twitter to get tweets. However, there is a method around this known as padding or *JSONP*. (I found out after the video that Twitter no longer offers this API without authentication, Instead I decided to use the [Meetup API for cities](http://www.meetup.com/meetup_api/docs/2/cities/)) . In the example [08-1-ngResource.html](https://github.com/zafarali/learning-angular/blob/master/08-1-ngResource.html) I override the usual GET method of the resource object with the JSONP method which allows me to access the Meetup API and retrieve nearest cities. Note that not all websites provide a JSONP enabled API. The page is made following the tutorial from [egghead.io](https://www.youtube.com/watch?v=IRelx4-ISbs). [Meetup Cities API](http://www.meetup.com/meetup_api/docs/2/cities/). **Read the comments in 08-1-ngResource.html for in depth explanation of what is happening**   \n\nAnother conversation I found online regarding the `ngResource` module is that the above example doesn't demonstrate its complete power. Infact `$resource` should be used when we have objects to `.get()`, manipulate and then `.$save()` back onto the server.   \n\n### Interesting things to know\nHere are a few things I felt like covering to give us a nice break from the very serious factory, provider, module, routing stuff we have been getting into\n#### `ngAnimate`\nAnimations in AngularJS require us to inject a special module known as `ngAnimate` which adds special classes to elements that can be animated in special ways. In [08-0-ngAnimate.html](https://github.com/zafarali/learning-angular/blob/master/08-0-ngAnimate.html) we see three separate cases of how these are done using CSS.\nThe key thing to remember here is that while the animation is being executed (i.e the transitions and the animations), the class of the element will have `.ng-enter-active`.\n\n#### Scope Communication\nWe have seen previously that there are ways to watch for events/changes using `$watch` but here we introduce another way known as `$on`. This monitors the scope for an event of a name. For example:\n```javascript\nscope.$on('myEventName', function(event, param1, param2, ...) {\n\tconsole.log(param1 + ' ' + param2);\n\tscope.doEvent(param1, param2);\n});\n\n//The above can be invoked by:\nscope.$emit('myEventName', 'Hello', 'World');\n//or\nscope.$broadcast('myEventName', 'Bye', 'World');\n```\nWhat is the difference between `$emit` and `$broadcast`? As mentioned previously `$emit` propagates the event upwards and all controllers listening for `myEventName` in the parent scopes will be alerted. `$broadcast` does the opposite and propagates the event downwards. Note that both these events will also execute in their own scopes.  \n\nA new example here [08-2-onEmitBroadcast.html](https://github.com/zafarali/learning-angular/blob/master/08-2-onEmitBroadcast.html) demonstrates this. Remember that declaring a new controller automatically creates a new scope. The page is also demonstrates inherited scopes and overriding properties.\nI've realized that this is one of AngularJS' most powerful feature.\n\n### Forms\n*Content from this section (Forms) is based off the course [Shaping Up With AngularJS](http://campus.codeschool.com/courses/shaping-up-with-angular-js/)*  \nRemember when we discussed [Angluar Classes above](https://github.com/zafarali/learning-angular#angular-classes)? AngluarJS provides us with a couple of other nice tricks and features that make form validations easier. Let's look at each of them step by step and then do an example:  \n- `ng-submit` is an attribute of the `\u003cform\u003e` element that has the function will be invoked when the user clicks the 'submit' button. Alternatively this function can also be in `ng-click` of the `\u003cbutton\u003e` element.  \n- `formname.$valid` is an object available on the global scope where formname is the `name` attribute of the `\u003cform\u003e` element. From this we can see that AngluarJS does alot behind the scene for us and will automatically validate the form. Returns `true` or `false`.\n- Coupling the `$valid` with the Angluar Classes we can make a very interactive form! See [here for example](https://github.com/zafarali/learning-angular/blob/master/09-0-forms.html)\n\n### `$compile` and Ustable Templates\nSo we've wired up our web app with all this AngularJS goodness, everything has rendered and now ready for some juicy interactivity. I recently came across the problem of having to inject new HTML-Angular content into the page when the user clicks on something without changing the view/refreshing the page. I tried to use `$scope.$apply()`, or `$scope.$digest()` but these didn't work. They I figured that Angular doesn't KNOW about this new HTML content of our page.I found a function known as `$compile` that can help us achieve the required functionality.  \nThe example is demonstrated in [09-1-compile.html](https://github.com/zafarali/learning-angular/blob/master/09-1-compile.html) where I inject some HTML after the page has loaded. Something that might confuse us: \n```javascript \n\t//.....\n\t//compilation is a two step process:\n\tvar compiledStuff = $compile(myHTML);\n\t//this returns a function that must be bound to a scope:\n\tcompiledStuff($scope);\n```\t\nNow we should be able to load any HTML we need into our page using `$compile`. However, note that if an AngularJS alternative exists, it is recommended to use that.\n\n### Providers and Injectors (advanced)\n- [ ] To be completed:  \n#### Providers  \n#### Injectors\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzafarali%2Flearning-angular","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fzafarali%2Flearning-angular","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzafarali%2Flearning-angular/lists"}