Friday, April 13, 2018

Angular



@Component({
  selector: 'my-app',
  template: '<h1>Ultra Racing</h1>'
}) 


@ComponentUsed to apply our component decorator to our class.Decorators are a TypeScript feature.
  selector :The CSS selector for the HTML element where we want the component to
 load. The content we want to load inside our selector. 
  template






BrowserModule: Module needed for running Angular websites.

platformBrowserDynamic : Angular library that will render the website.
USING INTERPOLATION TO PRINT PROPERTIES

@Component({
 selector: 'my-app'
 template:'

{{title}}

' //interploation 
})

import {NgModule,Component} from '@angular/core'
import {BrowserModule} from '@angular/platform-broswer'
import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';






ngOnInit() {
  this.carParts = CARPARTS;
} 


1.5 Our First Component

index.html


<html>
  <head>
    <title>Racing App</title>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" href="styles.css">

    
     
    <script src="https://unpkg.com/core-js/client/shim.min.js"></script>

    <script src="https://unpkg.com/zone.js@0.6.25?main=browser"></script>
    <script src="https://unpkg.com/reflect-metadata@0.1.8"></script>
    <script src="https://unpkg.com/systemjs@0.19.39/dist/system.src.js"></script>

    
    <script src="systemjs.config.js"></script>

    <script>
      System.import('app/main').catch(function(err){ console.error(err);  });
    </script>
  </head>

  
  <body>
    <racing-app> <h1>Loading...</h1></racing-app>
  </body>
</html>

app/main.ts

import { NgModule, Component } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';

@Component({
  selector:'racing-app',
  template:`

{{heading}}

`
}) class AppComponent { heading = "Ultra Racing Schedule" } @NgModule({ imports: [ BrowserModule ], declarations: [AppComponent], bootstrap:[AppComponent] }) class AppModule {} platformBrowserDynamic() .bootstrapModule(AppModule);

______________________________________________________________________________

1.6 Making It Dynamic

app/main.ts

import { NgModule, Component } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';

@Component({
  selector: 'racing-app',
  template: `
    

{{ heading }}

{{race.name}}

{{race.date}} {{race.about}} ` }) class AppComponent { heading = "Ultra Racing Schedule" race = { "id": 1, "name": "Daytona Thunderdome", "date": new Date('2512-01-04T14:00:00'), "about": "Race through the ruins of an ancient Florida battle arena.", "entryFee": 3200 } } @NgModule({ imports: [ BrowserModule ], declarations: [ AppComponent ], bootstrap: [ AppComponent ] }) class AppModule {} platformBrowserDynamic() .bootstrapModule(AppModule);


______________________________________________________________________________

2.4 Looping


______________________________________________________________________________

2.5 Conditionals 


______________________________________________________________________________

2.9 Methods 

At the bottom of our template we've added a place to display our total cost. Our total cost will be calculated by summing up the entryFee properties of ONLY the races we are racing in ( isRacing istrue). Write a method named totalCost() in our AppComponent that returns this value.


app/main.ts


import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { BrowserModule } from '@angular/platform-browser';
import { NgModule, Component } from '@angular/core';

@Component({
  selector: 'racing-app',
  template: `
  

{{heading}}

  • {{race.name}} {{race.entryFee | currency:'USD':true}}

    {{race.date | date:'MMM d, y, h:MM a'}} {{race.about}}

    Already Racing


    Total cost: {{totalCost() | currency:'USD':true}}

    ` }) export class AppComponent { heading = "Ultra Racing Schedule" cash = 10000; races = [{ "id": 1, "name": "Daytona Thunderdome", "date": new Date('2512-01-04T14:00:00'), "about": "Race through the ruins of an ancient Florida battle arena.", "entryFee": 3200, "isRacing": false }, { "id": 2, "name": "San Francisco Ruins", "date": new Date('2512-07-03T20:00:00'), "about": "Drift down the streets of a city almost sunk under the ocean.", "entryFee": 4700, "isRacing": true }, { "id": 3, "name": "New York City Skyline", "date": new Date('2512-07-12T21:00:00'), "about": "Fly between buildings in the electronic sky.", "entryFee": 4300, "isRacing": true }]; totalCost() { let sum = 0; for (let race of this.races){ if(race.isRacing) { sum += race.entryFee; } } return sum; } } @NgModule({ imports: [ BrowserModule ], declarations: [ AppComponent ], bootstrap: [ AppComponent ] }) class AppModule {} platformBrowserDynamic().bootstrapModule(AppModule);
    ______________________________________________________________________________


    3.3 Refactoring Classes

    Both our app.component.ts and our races.component.ts are missing the export keyword to allow their classes to be imported. Could you add them where they’re needed?

    app/app.component.ts

    import { Component } from '@angular/core';
    
    @Component({
      selector: 'racing-app',
      template: `
        

    {{heading}}

    my-races ` }) export class AppComponent { heading = "Ultra Racing Schedule" }

    app/races.component.ts

    import { Component } from '@angular/core';
    
    @Component({
      selector: 'my-races',
      template: `
        

    Cash left to enter races: {{cashLeft() | currency:'USD':true}}

    • {{race.name}} {{race.entryFee | currency:'USD':true}}

      {{race.date | date:'MMM d, y, h:MM a'}} {{race.about}}

      Already Racing


      Total cost: {{totalCost() | currency:'USD':true}}

      ` }) export class RacesComponent { heading = "Ultra Racing Schedule" cash = 10000; races = [{ "id": 1, "name": "Daytona Thunderdome", "date": new Date('2512-01-04T14:00:00'), "about": "Race through the ruins of an ancient Florida battle arena.", "entryFee": 3200, "isRacing": false }, { "id": 2, "name": "San Francisco Ruins", "date": new Date('2512-07-03T20:00:00'), "about": "Drift down the streets of a city almost sunk under the ocean.", "entryFee": 4700, "isRacing": true }, { "id": 3, "name": "New York City Skyline", "date": new Date('2512-07-12T21:00:00'), "about": "Fly between buildings in the electronic sky.", "entryFee": 4300, "isRacing": true }]; totalCost() { let sum = 0; for (let race of this.races) { if (race.isRacing) sum += race.entryFee; } return sum; } cashLeft() { return this.cash - this.totalCost(); } }

      app/main.ts

      import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
      import { BrowserModule } from '@angular/platform-browser';
      import { NgModule } from '@angular/core';
      import { AppComponent } from './app.component';
      import { RacesComponent } from './races.component';
      
      @NgModule({
        imports: [ BrowserModule ],
        declarations: [ AppComponent,RacesComponent ],
        bootstrap: [ AppComponent ]
      })
      class AppModule {}
      
      platformBrowserDynamic().bootstrapModule(AppModule);

      ______________________________________________________________________________


      3.5 Adding HTML and CSS 

      app/races.component.ts

      import { Component } from '@angular/core';
      
      @Component({
        selector: 'my-races',
        templateUrl:'app/races.component.html',
        styleUrls['app/races.component.css'];
      })
      export class RacesComponent {
        heading = "Ultra Racing Schedule"
        cash = 10000;
        races = [{
          "id": 1,
          "name": "Daytona Thunderdome",
          "date": new Date('2512-01-04T14:00:00'),
          "about": "Race through the ruins of an ancient Florida battle arena.",
          "entryFee": 3200,
          "isRacing": false
        }, {
          "id": 2,
          "name": "San Francisco Ruins",
          "date": new Date('2512-07-03T20:00:00'),
          "about": "Drift down the streets of a city almost sunk under the ocean.",
          "entryFee": 4700,
          "isRacing": true
        }, {
          "id": 3,
          "name": "New York City Skyline",
          "date": new Date('2512-07-12T21:00:00'),
          "about": "Fly between buildings in the electronic sky.",
          "entryFee": 4300,
          "isRacing": true
        }];
      
        totalCost() {
          let sum = 0;
          for (let race of this.races) {
            if (race.isRacing) sum += race.entryFee;
          }
          return sum;
        }
      
        cashLeft() {
          return this.cash - this.totalCost();
        }
      
      }




      ______________________________________________________________________________

      DATA ORGANIZATION

      3.8 Modeling and Mocking 


      app/race.ts

      export class Race {
        id: number;
        name: string;
        date:  Date;
        about: string;
        entryFee: number;
        isRacing: boolean;
      }
      

      app/mocks.ts

      import { Race } from './race';
      
      export const RACES: races[]=[{
        "id": 1,
        "name": "Daytona Thunderdome",
        "date": new Date('2512-01-04T14:00:00'),
        "about": "Race through the ruins of an ancient Florida battle arena.",
        "entryFee": 3200,
        "isRacing": false
      }, {
        "id": 2,
        "name": "San Francisco Ruins",
        "date": new Date('2512-07-03T20:00:00'),
        "about": "Drift down the streets of a city almost sunk under the ocean.",
        "entryFee": 4700,
        "isRacing": true
      }, {
        "id": 3,
        "name": "New York City Skyline",
        "date": new Date('2512-07-12T21:00:00'),
        "about": "Fly between buildings in the electronic sky.",
        "entryFee": 4300,
        "isRacing": true
      }];
      

      app/races.component.ts

      import { Component } from '@angular/core';
      import { Race } from './race';
      import { RACES } from './mocks';
      
      @Component({
        selector: 'my-races',
        templateUrl: 'app/races.component.html',
        styleUrls:['app/races.component.css']
      })
      export class RacesComponent {
        heading = "Ultra Racing Schedule"
        cash = 10000;
        races: Race[];
        ngOnInit(){
          this.races = RACES;
        }
      
        totalCost() {
          let sum = 0;
          for (let race of this.races) {
            if (race.isRacing) sum += race.entryFee;
          }
          return sum;
        }
      
        cashLeft() {
          return this.cash - this.totalCost();
        }
      
      }







      ______________________________________________________________________________

      DATA  BINDING BOOST

      4.1 Property & Class Binding

      We've gone ahead and applied new HTML and CSS to our app to make it prettier. We also have two new fields in our model and mocks: image and imageDescription.

      app/races.component.html

      <main class="container" role="main">
      <h2>Cash left to enter races: <span>{{cashLeft() | currency:'USD':true}}</span> </h2>
      <ul>
        <li class="card" *ngFor="let race of races"  [class.racing]="race.isRacing" >
          <div class="panel-body">
            <div class="photo">
              <img  [alt]="race.imageDescription"  [src]= "race.image" >
            </div>
            <table class="race-info">
              <tr>
                <td>
                  <h3>{{race.name}}</h3>
                  <p class="date">{{race.date | date:'MMM d, y, h:MM a'}}</p>
                  <p class="description">{{race.about}}</p>
                </td>
                <td>
                  <p class="price">{{race.entryFee | currency:'USD':true}}</p>
                </td>
                <td>
                  <button class="button" *ngIf="!race.isRacing">Enter Race</button>
                  <div *ngIf="race.isRacing">
                    <p class="status">Racing</p>
                    <button class="button-cancel">Cancel Race</button>
                  </div>
                </td>
              </tr>
            </table>
          </div>
        </li>
      </ul>
      <div class="price-total">
        <h3>Total cost:</h3>
        <p>{{totalCost() | currency:'USD':true}}</p>
      </div>
      </main>




      ______________________________________________________________________________


      Time to implement the "Enter Race" button and "Cancel Race" link.


      app/races.component.html

      <main class="container" role="main">
      <h2>Cash left to enter races: <span>{{cashLeft() | currency:'USD':true}}</span> </h2>
      <ul>
        <li class="card" *ngFor="let race of races" [class.racing]="race.isRacing" >
          <div class="panel-body">
            <div class="photo">
              <img [src]="race.image" [alt]="race.imageDescription">
            </div>
            <table class="race-info">
              <tr>
                <td>
                  <h3>{{race.name}}</h3>
                  <p class="date">{{race.date | date:'MMM d, y, h:MM a'}}</p>
                  <p class="description">{{race.about}}</p>
                </td>
                <td>
                  <p class="price">{{race.entryFee | currency:'USD':true}}</p>
                </td>
                <td>
                  <button class="button" *ngIf="!race.isRacing" (click)="enterRace(race)"  >Enter Race</button>
                  <div *ngIf="race.isRacing">
                    <p class="status">Racing</p>
                    <button class="button-cancel" (click)="cancelRace(race)"  >Cancel Race</button>
                  </div>
                </td>
              </tr>
            </table>
          </div>
        </li>
      </ul>
      <div class="price-total">
        <h3>Total cost:</h3>
        <p>{{totalCost() | currency:'USD':true}}</p>
      </div>
      </main>
      

      app/races.component.ts

      import { Component } from '@angular/core';
      import { Race } from './race';
      import { RACES } from './mocks';
      
      @Component({
        selector: 'my-races',
        templateUrl: 'app/races.component.html',
        styleUrls:['app/races.component.css']
      })
      export class RacesComponent {
        heading = "Ultra Racing Schedule"
        cash = 10000;
        races: Race[];
      
        ngOnInit() {
          this.races = RACES;
        }
      
        totalCost() {
          let sum = 0;
          for (let race of this.races) {
            if (race.isRacing) sum += race.entryFee;
          }
          return sum;
        }
      
        cashLeft() {
          return this.cash - this.totalCost();
        }
        cancelRace(race){
         race.isRacing = false;
        }
      enterRace(race){
        if(this.cashLeft()>race.entryFee){   
          race.isRacing = true;
        }else{
             race.isRacing = false;
          alert( "You don't have enough cash");
        }  
      }
      
      
      }


      ______________________________________________________________________________


      Sending Event Data





      4.8 Input Binding

      app/races.component.html

      <main class="container" role="main">
      <h2>Money for racing: <input type="text" class="cash" [(ngModel)]="cash"></h2>
      <h2>Cash left to enter races: <span>{{cashLeft() | currency:'USD':true}}</span> </h2>
      <ul>
        <li class="card" *ngFor="let race of races" [class.racing]="race.isRacing" >
          <div class="panel-body">
            <div class="photo">
              <img [src]="race.image" [alt]="race.imageDescription">
            </div>
            <table class="race-info">
              <tr>
                <td>
                  <h3>{{race.name}}</h3>
                  <p class="date">{{race.date | date:'MMM d, y, h:MM a'}}</p>
                  <p class="description">{{race.about}}</p>
                </td>
                <td>
                  <p class="price">{{race.entryFee | currency:'USD':true}}</p>
                </td>
                <td>
                  <button class="button" *ngIf="!race.isRacing" (click)="enterRace(race)">Enter Race</button>
                  <div *ngIf="race.isRacing">
                    <p class="status">Racing</p>
                    <button class="button-cancel" (click)="cancelRace(race)">Cancel Race</button>
                  </div>
                </td>
              </tr>
            </table>
          </div>
        </li>
      </ul>
      <div class="price-total">
        <h3>Total cost:</h3>
        <p>{{totalCost() | currency:'USD':true}}</p>
      </div>
      </main>

      This symbol [()] is sometimes called?

      banana in a box

      ______________________________________________________________________________






      5.3 Moving to a Service 175 PTS


      It's time to move our mocks into services for our racing schedule app. We've gone ahead and started creating a race.service.ts file for you. Please note that this is a RaceServiceclass, not RacingDataService class like in the slides. We need your help hooking it all up.
      • app/race.service.ts

        import { RACES } from './mocks';
        import { Injectable } from '@angular/core';
        
        @Injectable()
        export class RaceService {
          getRaces() {
            return RACES;
          }
        }
        
      • app/main.ts

        import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
        import { BrowserModule } from '@angular/platform-browser';
        import { NgModule } from '@angular/core';
        import { FormsModule } from '@angular/forms';
        import { AppComponent } from './app.component';
        import { RacesComponent } from './races.component';
        import { RaceService } from './race.service';
        
        @NgModule({
          imports: [ BrowserModule, FormsModule ],
          declarations: [ AppComponent ],
          providers: [ RaceService ],
          bootstrap: [ AppComponent ]
        })
        class AppModule {}
        
        platformBrowserDynamic().bootstrapModule(AppModule);
        
      • app/races.component.ts

        import { Component } from '@angular/core';
        import { Race } from './race';
        import { RaceService } from './race.service';
        
        @Component({
          selector: 'my-races',
          templateUrl: 'app/races.component.html',
          styleUrls:['app/races.component.css']
        })
        export class RacesComponent {
          heading = "Ultra Racing Schedule"
          cash = 10000;
          races: Race[];
        
          constructor(private raceService: RaceService) { }
        
          ngOnInit() {
            this.races = this.raceService.getRaces();
          }
        
          totalCost() {
            let sum = 0;
            for (let race of this.races) {
              if (race.isRacing) sum += race.entryFee;
            }
            return sum;
          }
        
          cashLeft() {
            return this.cash - this.totalCost();
          }
        
          enterRace(race) {
            if (this.cashLeft() > race.entryFee) {
              race.isRacing = true;
            } else {
              alert("You don't have enough cash");
            }
          }
        
          cancelRace(race) {
            race.isRacing = false;
          }
        
        }


      ______________________________________________________________________________






      5.5 Over the Internet 250 PTS


      We've gone ahead and created a races.json file for you — check it out. Let's import and usehttp to fetch our data.

      ______________________________________________________________________________




      ______________________________________________________________________________













      ______________________________________________________________________________


      Exercise 1: MODULE


      app.js

      var app = angular.module('gemStore',[]);
      

      index.html

      
      <html ng-app ='gemStore'>
        <head>
          <link rel="stylesheet" type="text/css" href="bootstrap.min.css" />
          <script type="text/javascript" src="angular.min.js"></script>
          <script type="text/javascript" src="app.js"></script>
        </head>
        <body>
          <h1>{{"Hello, Angular!"}}</h1>
        </body>
      </html>


      Exercise 3: CONTROLLERS


      app.js

      (function(){
        var gem = { name: 'Azurite', price: 2.95 };
        var app = angular.module('gemStore', []);
        app.controller('StoreController',function(){
          this.product = gem;
          
        });
      })();
      

      index.html

      
      <html ng-app="gemStore">
        <head>
          <link rel="stylesheet" type="text/css" href="bootstrap.min.css" />
          <script type="text/javascript" src="angular.min.js"></script>
          <script type="text/javascript" src="app.js"></script>
        </head>
        <body ng-controller="StoreController as store">
          <div class="product row">
            <h3>
              {{store.product.name}}
              <em class="pull-right"> {{store.product.price}}</em>
            </h3>
          </div>
        </body>
      </html>


      Exercise 4: NG-SHOW/NG-HIDE: 
      NOTICE: The value is in quotes

      Index.html

      
      <html ng-app="gemStore">
        <head>
          <link rel="stylesheet" type="text/css" href="bootstrap.min.css" />
          <script type="text/javascript" src="angular.min.js"></script>
          <script type="text/javascript" src="app.js"></script>
        </head>
        <body class="container" ng-controller="StoreController as store">
          <div class="product row" ng-hide = "store.product.soldOut">
            <h3>
              {{store.product.name}}
              <em class="pull-right">${{store.product.price}}</em>
            </h3>
            <button ng-show = "store.product.canPurchase">Add to Cart</button>
          </div>
        </body>
      </html>


      Exercise 5: NG -REPEAT

      app.js

      (function() {
        var app = angular.module('gemStore', []);
      
        app.controller('StoreController', function(){
          this.products = gems;
        });
      
        var gems = [
          { name: 'Azurite', price: 2.95 },
          { name: 'Bloodstone', price: 5.95 },
          { name: 'Zircon', price: 3.95 }
        ];
      })();
      

      index.html

      
      <html ng-app="gemStore">
        <head>
          <link rel="stylesheet" type="text/css" href="bootstrap.min.css" />
          <script type="text/javascript" src="angular.min.js"></script>
          <script type="text/javascript" src="app.js"></script>
        </head>
        <body class="container" ng-controller="StoreController as store">
          <div class="product row" ng-repeat = "product in store.products">
            <h3>
              {{product.name}}
              <em class="pull-right">${{product.price}}</em>
            </h3>
          </div>
        </body>
      </html>


      Exercise 6: FILTERS


      index.html

      
      <html ng-app="gemStore">
        <head>
          <link rel="stylesheet" type="text/css" href="bootstrap.min.css" />
          <script type="text/javascript" src="angular.min.js"></script>
          <script type="text/javascript" src="app.js"></script>
        </head>
        <body class="container" ng-controller="StoreController as store">
          <div class="product row" ng-repeat="product in store.products">
            <h3>
              {{product.name}}
              <em class="pull-right">{{product.price | currency }}</em>
            </h3>
          </div>
        </body>
      </html>


      Exercise 7: FILTERS


      index.html

      
      <html ng-app="gemStore">
        <head>
          <link rel="stylesheet" type="text/css" href="bootstrap.min.css" />
          <script type="text/javascript" src="angular.min.js"></script>
          <script type="text/javascript" src="app.js"></script>
        </head>
        <body ng-controller="StoreController as store">
          
          <div class="list-group">
            
            <div class="list-group-item" ng-repeat="product in store.products">
              <h3>
                {{product.name}}
                <em class="pull-right">{{product.price | currency}}</em>
              </h3>
              
              <div class="gallery">
                <img ng-src = "{{product.images[0]}}" />
              </div>
            </div>
          </div>
        </body>
      </html>


      Exercise 8: DISPLAYING THE FIRST IMAGE
      ng-src

      index.html

      
      <html ng-app="gemStore">
        <head>
          <link rel="stylesheet" type="text/css" href="bootstrap.min.css" />
          <script type="text/javascript" src="angular.min.js"></script>
          <script type="text/javascript" src="app.js"></script>
        </head>
        <body class="list-group" ng-controller="StoreController as store">
          
          <div class="list-group-item" ng-repeat="product in store.products">
            <h3>{{product.name}} <em class="pull-right">{{product.price | currency}}</em></h3>
      
            
            <div class="gallery">
              <div class="img-wrap">
                <img ng-src="{{product.images[0]}}" />
              </div>
              <ul class="img-thumbnails clearfix">
                <li class="small-image pull-left thumbnail" ng-repeat ="image in product.images">
                  <img ng-src="{{image}}" />
                </li>
              </ul>
            </div>
          </div>
        </body>
      </html>

      Exercise 9 : CREATING AND DISPLAYING  TAB CONTROLLER


      app.js

      (function() {
        var app = angular.module('gemStore', []);
      
        app.controller('StoreController', function(){
          this.products = gems;
        });
      
       app.controller('TabController', function(){
         this.tab = 1;
         this.setTab = function(ntab){
              this.tab = ntab;
         };
           this.isSet = function(ntab){
              return this.tab == ntab;
         };
        });
      
      
        var gems = [
            {
              name: 'Azurite',
              description: "Some gems have hidden qualities beyond their luster, beyond their shine... Azurite is one of those gems.",
              shine: 8,
              price: 110.50,
              rarity: 7,
              color: '#CCC',
              faces: 14,
              images: [
                "images/gem-02.gif",
                "images/gem-05.gif",
                "images/gem-09.gif"
              ],
              reviews: [{
                stars: 5,
                body: "I love this gem!",
                author: "joe@example.org",
                createdOn: 1397490980837
              }, {
                stars: 1,
                body: "This gem sucks.",
                author: "tim@example.org",
                createdOn: 1397490980837
              }]
            },
            {
              name: 'Bloodstone',
              description: "Origin of the Bloodstone is unknown, hence its low value. It has a very high shine and 12 sides, however.",
              shine: 9,
              price: 22.90,
              rarity: 6,
              color: '#EEE',
              faces: 12,
              images: [
                "images/gem-01.gif",
                "images/gem-03.gif",
                "images/gem-04.gif",
              ],
              reviews: [{
                stars: 3,
                body: "I think this gem was just OK, could honestly use more shine, IMO.",
                author: "JimmyDean@example.org",
                createdOn: 1397490980837
              }, {
                stars: 4,
                body: "Any gem with 12 faces is for me!",
                author: "gemsRock@example.org",
                createdOn: 1397490980837
              }]
            },
            {
              name: 'Zircon',
              description: "Zircon is our most coveted and sought after gem. You will pay much to be the proud owner of this gorgeous and high shine gem.",
              shine: 70,
              price: 1100,
              rarity: 2,
              color: '#000',
              faces: 6,
              images: [
                "images/gem-06.gif",
                "images/gem-07.gif",
                "images/gem-09.gif"
              ],
              reviews: [{
                stars: 1,
                body: "This gem is WAY too expensive for its rarity value.",
                author: "turtleguyy@example.org",
                createdOn: 1397490980837
              }, {
                stars: 1,
                body: "BBW: High Shine != High Quality.",
                author: "LouisW407@example.org",
                createdOn: 1397490980837
              }, {
                stars: 1,
                body: "Don't waste your rubles!",
                author: "nat@example.org",
                createdOn: 1397490980837
              }]
            }
          ];
      })();

      index.html

      
      <html ng-app="gemStore">
        <head>
          <link rel="stylesheet" type="text/css" href="bootstrap.min.css" />
          <script type="text/javascript" src="angular.min.js"></script>
          <script type="text/javascript" src="app.js"></script>
        </head>
        <body class="list-group" ng-controller="StoreController as store">
          <header>
            <h1 class="text-center">Flatlander Crafted Gems</h1>
            <h2 class="text-center">– an Angular store –</h2>
          </header>
          <div class="list-group-item" ng-repeat="product in store.products">
            <h3>
              {{product.name}}
              <em class="pull-right">{{product.price | currency}}</em>
            </h3>
            <section ng-show="product.images.length">
              <img ng-src="{{product.images[0]}}" />
              <ul class="list-inline thumbs">
                <li class="thumbnail" ng-repeat="image in product.images">
                  <img ng-src="{{image}}" />
                </li>
              </ul>
            </section>
      
            <section class="tab" ng-controller="TabController as ctrl">
              <ul class="nav nav-pills">
                <li ng-class = "{active:ctrl.isSet(1)}">
                  <a href ng-click = "ctrl.setTab(1)">Description</a></li>
                <li ng-class = "{active:ctrl.isSet(2)}">
                  <a href   ng-click = "ctrl.setTab(2)">Specs</a></li>
                <li ng-class = "{active:ctrl.isSet(3)}">
                  <a href   ng-click = "ctrl.setTab(3)">Reviews</a></li>
              </ul>
              <div ng-show = "ctrl.isSet(1)">
                <h4>Description</h4>
                <blockquote>{{product.description}}</blockquote>
              </div>
              <div ng-show = "ctrl.isSet(2)">
                <h4>Specs</h4>
                <blockquote>Shine:{{product.shine}} </blockquote>
              </div>
              <div  ng-show = "ctrl.isSet(3)">
                <h4>Reviews</h4>
                <blockquote></blockquote>
              </div>
            </section>
          </div>
        </body>
      </html>


      Exercise 10 : CREATE & USING GALLERY CONTROLLER

      app.js

      (function() {
        var app = angular.module('gemStore', []);
      
       app.controller('GalleryController',function(){
          this.current = 0;
          this.setCurrent = function(value) {
               this.current = value || 0;
            };
      
        });
      
        app.controller('StoreController', function(){
          this.products = gems;
        });
      
        app.controller('TabController', function(){
          this.tab = 1;
      
          this.setTab = function(newValue){
            this.tab = newValue;
          };
      
          this.isSet = function(tabName){
            return this.tab === tabName;
          };
        });
      
        var gems = [
          {
            name: 'Azurite',
            description: "Some gems have hidden qualities beyond their luster, beyond their shine... Azurite is one of those gems.",
            shine: 8,
            price: 110.50,
            rarity: 7,
            color: '#CCC',
            faces: 14,
            images: [
              "images/gem-02.gif",
              "images/gem-05.gif",
              "images/gem-09.gif"
            ],
            reviews: [{
              stars: 5,
              body: "I love this gem!",
              author: "joe@example.org",
              createdOn: 1397490980837
            }, {
              stars: 1,
              body: "This gem sucks.",
              author: "tim@example.org",
              createdOn: 1397490980837
            }]
          },
          {
            name: 'Bloodstone',
            description: "Origin of the Bloodstone is unknown, hence its low value. It has a very high shine and 12 sides, however.",
            shine: 9,
            price: 22.90,
            rarity: 6,
            color: '#EEE',
            faces: 12,
            images: [
              "images/gem-01.gif",
              "images/gem-03.gif",
              "images/gem-04.gif",
            ],
            reviews: [{
              stars: 3,
              body: "I think this gem was just OK, could honestly use more shine, IMO.",
              author: "JimmyDean@example.org",
              createdOn: 1397490980837
            }, {
              stars: 4,
              body: "Any gem with 12 faces is for me!",
              author: "gemsRock@example.org",
              createdOn: 1397490980837
            }]
          },
          {
            name: 'Zircon',
            description: "Zircon is our most coveted and sought after gem. You will pay much to be the proud owner of this gorgeous and high shine gem.",
            shine: 70,
            price: 1100,
            rarity: 2,
            color: '#000',
            faces: 6,
            images: [
              "images/gem-06.gif",
              "images/gem-07.gif",
              "images/gem-09.gif"
            ],
            reviews: [{
              stars: 1,
              body: "This gem is WAY too expensive for its rarity value.",
              author: "turtleguyy@example.org",
              createdOn: 1397490980837
            }, {
              stars: 1,
              body: "BBW: High Shine != High Quality.",
              author: "LouisW407@example.org",
              createdOn: 1397490980837
            }, {
              stars: 1,
              body: "Don't waste your rubles!",
              author: "nat@example.org",
              createdOn: 1397490980837
            }]
          }
        ];
      })();


      
      <html ng-app="gemStore">
        <head>
          <link rel="stylesheet" type="text/css" href="bootstrap.min.css" />
          <script type="text/javascript" src="angular.min.js"></script>
          <script type="text/javascript" src="app.js"></script>
        </head>
        <body class="list-group" ng-controller="StoreController as store">
          <header>
            <h1 class="text-center">Flatlander Crafted Gems</h1>
            <h2 class="text-center">– an Angular store –</h2>
          </header>
          <div class="list-group-item" ng-repeat="product in store.products">
            <h3>
              {{product.name}}
              <em class="pull-right">{{product.price | currency}}</em>
            </h3>
      
            
            <div class='gallery' ng-show="product.images.length" ng-controller="GalleryController as gallery">
              <img ng-src="{{product.images[gallery.current]}}" />
              <ul class="list-inline thumbs">
                <li class="thumbnail" ng-repeat="image in product.images">
                  <img ng-src="{{image}}" />
                </li>
              </ul>
            </div>
      
            <section class="tab" ng-controller="TabController as tab">
              <ul class="nav nav-pills">
                <li ng-class="{ active: tab.isSet(1) }">
                  <a href ng-click="tab.setTab(1)">Description</a></li>
                <li ng-class="{ active: tab.isSet(2) }">
                  <a href ng-click="tab.setTab(2)">Specs</a></li>
                <li ng-class="{ active: tab.isSet(3) }">
                  <a href ng-click="tab.setTab(3)">Reviews</a></li>
              </ul>
              <div ng-show="tab.isSet(1)">
                <h4>Description</h4>
                <blockquote>{{product.description}}</blockquote>
              </div>
              <div ng-show="tab.isSet(2)">
                <h4>Specs</h4>
                <blockquote>Shine: {{product.shine}}</blockquote>
              </div>
              <div ng-show="tab.isSet(3)">
                <h4>Reviews</h4>
              </div>
            </section>
          </div>
        </body>
      </html>


      Exercise 10 : GALLERY CONTROLLER

      index.html

      
      <html ng-app="gemStore">
        <head>
          <link rel="stylesheet" type="text/css" href="bootstrap.min.css" />
          <script type="text/javascript" src="angular.min.js"></script>
          <script type="text/javascript" src="app.js"></script>
        </head>
      
        <body ng-controller="StoreController as store">
          
          <header>
            <h1 class="text-center">Flatlander Crafted Gems</h1>
            <h2 class="text-center">– an Angular store –</h2>
          </header>
      
          
          <div class="list-group">
            
            <div class="list-group-item" ng-repeat="product in store.products">
              <h3>{{product.name}} <em class="pull-right">{{product.price | currency}}</em></h3>
      
              
              <div ng-controller="GalleryController as gallery"  ng-show="product.images.length">
                <div class="img-wrap">
                  <img ng-src="{{product.images[gallery.current]}}" />
                </div>
                <ul class="img-thumbnails clearfix">
                  <li class="small-image pull-left thumbnail" ng-repeat="image in product.images">
                    <img ng-src="{{image}}" />
                  </li>
                </ul>
              </div>
      
              
              <section ng-controller="TabController as tab">
                <ul class="nav nav-pills">
                  <li ng-class="{ active:tab.isSet(1) }">
                    <a href="" ng-click="tab.setTab(1)">Description</a>
                  </li>
                  <li ng-class="{ active:tab.isSet(2) }">
                    <a href="" ng-click="tab.setTab(2)">Specs</a>
                  </li>
                  <li ng-class="{ active:tab.isSet(3) }">
                    <a href="" ng-click="tab.setTab(3)">Reviews</a>
                  </li>
                </ul>
      
                
                <div ng-show="tab.isSet(1)">
                  <h4>Description</h4>
                  <blockquote>{{product.description}}</blockquote>
                </div>
      
                
                <div ng-show="tab.isSet(2)">
                  <h4>Specs</h4>
                  <blockquote>Shine: {{product.shine}}</blockquote>
                </div>
      
                
                <div ng-show="tab.isSet(3)">
      
                  
                  <ul>
                    <h4>Reviews</h4>
                    <li ng-repeat="review in product.reviews">
                      <blockquote>
                        <strong>{{review.stars}} Stars</strong>
                        {{review.body}}
                        <cite class="clearfix">-{{review.author}}</cite>
                      </blockquote>
                    </li>
                  </ul>
      
                  
                  <form name="reviewForm">
                    
                    <blockquote>
                      {{review.body}}
                      <strong>{{review.stars}} Stars</strong>
                      
                      <cite class="clearfix">-{{review.author}}</cite>
                    </blockquote>
      
                    
                    <h4>Submit a Review</h4>
                    <fieldset class="form-group">
                      <select ng-model="review.stars" class="form-control" ng-options="stars for stars in [5,4,3,2,1]"  title="Stars">
                        <option value="">Rate the Product</option>
                      </select>
                    </fieldset>
                    <fieldset class="form-group">
                      <textarea ng-model="review.body" class="form-control" placeholder="Write a short review of the product..." title="Review"></textarea>
                    </fieldset>
                    <fieldset class="form-group">
                      <input ng-model="review.author" type="email" class="form-control" placeholder="jimmyDean@example.org" title="Email" />
                    </fieldset>
                    <fieldset class="form-group">
                      <input type="submit" class="btn btn-primary pull-right" value="Submit Review" />
                    </fieldset>
                  </form>
      
                </div>
      
              </section>
            </div>
          </div>
        </body>
      </html>



      Exercise 11 : CREATE & USING REVIEW CONTROLLER


      index.html


      
      <html ng-app="gemStore">
        <head>
          <link rel="stylesheet" type="text/css" href="bootstrap.min.css" />
          <script type="text/javascript" src="angular.min.js"></script>
          <script type="text/javascript" src="app.js"></script>
        </head>
        <body ng-controller="StoreController as store">
          <header>
            <h1 class="text-center">Flatlander Crafted Gems</h1>
            <h2 class="text-center">– an Angular store –</h2>
          </header>
          <div class="list-group">
            <div class="list-group-item" ng-repeat="product in store.products">
              <h3>{{product.name}} <em class="pull-right">{{product.price | currency}}</em></h3>
              <div ng-controller="GalleryController as gallery"  ng-show="product.images.length">
                <div class="img-wrap">
                  <img ng-src="{{product.images[gallery.current]}}" />
                </div>
                <ul class="img-thumbnails clearfix">
                  <li class="small-image pull-left thumbnail" ng-repeat="image in product.images">
                    <img ng-src="{{image}}" />
                  </li>
                </ul>
              </div>
              <section ng-controller="TabController as tab">
                <ul class="nav nav-pills">
                  <li ng-class="{ active:tab.isSet(1) }">
                    <a href="" ng-click="tab.setTab(1)">Description</a>
                  </li>
                  <li ng-class="{ active:tab.isSet(2) }">
                    <a href="" ng-click="tab.setTab(2)">Specs</a>
                  </li>
                  <li ng-class="{ active:tab.isSet(3) }">
                    <a href="" ng-click="tab.setTab(3)">Reviews</a>
                  </li>
                </ul>
                <div ng-show="tab.isSet(1)">
                  <h4>Description</h4>
                  <blockquote>{{product.description}}</blockquote>
                </div>
                <div ng-show="tab.isSet(2)">
                  <h4>Specs</h4>
                  <blockquote>Shine: {{product.shine}}</blockquote>
                </div>
                <div ng-show="tab.isSet(3)">
                  <ul>
                    <h4>Reviews</h4>
                    <li ng-repeat="review in product.reviews">
                      <blockquote>
                        <strong>{{review.stars}} Stars</strong>
                        {{review.body}}
                        <cite class="clearfix">—{{review.author}}</cite>
                      </blockquote>
                    </li>
                  </ul>
      
                  
                  <form name="reviewForm">
                    
                    <blockquote>
                      <strong> Stars</strong>
                      
                      <cite class="clearfix"></cite>
                    </blockquote>
      
                    
                    <h4>Submit a Review</h4>
                    <fieldset class="form-group">
                      <select ng-model ="review.stars" class="form-control" ng-options="stars for stars in [5,4,3,2,1]"  title="Stars">
                        <option value="">Rate the Product</option>
                      </select>
                    </fieldset>
                    <fieldset class="form-group">
                      <textarea ng-model ="review.body" class="form-control" placeholder="Write a short review of the product..." title="Review"></textarea>
                    </fieldset>
                    <fieldset class="form-group">
                      <input ng-model ="review.author"  type="email" class="form-control" placeholder="jimmyDean@example.org" title="Email" />
                    </fieldset>
                    <fieldset class="form-group">
                      <input type="submit" class="btn btn-primary pull-right" value="Submit Review" />
                    </fieldset>
                  </form>
      
                </div>
              </section>
            </div>
          </div>
        </body>
      </html>


      app.js

      (function() {
        var app = angular.module('gemStore', []);
      
        app.controller('StoreController', function(){
          this.products = gems;
        });
      
        app.controller('TabController', function(){
          this.tab = 1;
      
          this.setTab = function(tab){
            this.tab = tab;
          };
      
          this.isSet = function(tab){
            return (this.tab === tab);
          };
        });
      
        app.controller('GalleryController', function(){
          this.current = 0;
      
          this.setCurrent = function(index){
            this.current = index;
          };
        });
      
        app.controller('ReviewController',function(){
          this.review = {};
          this.addReview = function(product){
          product.reviews.push(this.review);
          this.review = {};
          };
         
        });
      
        var gems = [
          {
            name: 'Azurite',
            description: "Some gems have hidden qualities beyond their luster, beyond their shine... Azurite is one of those gems.",
            shine: 8,
            price: 110.50,
            rarity: 7,
            color: '#CCC',
            faces: 14,
            images: [
              "images/gem-02.gif",
              "images/gem-05.gif",
              "images/gem-09.gif"
            ],
            reviews: [{
              stars: 5,
              body: "I love this gem!",
              author: "joe@example.org",
              createdOn: 1397490980837
            }, {
              stars: 1,
              body: "This gem sucks.",
              author: "tim@example.org",
              createdOn: 1397490980837
            }]
          }, {
            name: 'Bloodstone',
            description: "Origin of the Bloodstone is unknown, hence its low value. It has a very high shine and 12 sides, however.",
            shine: 9,
            price: 22.90,
            rarity: 6,
            color: '#EEE',
            faces: 12,
            images: [
              "images/gem-01.gif",
              "images/gem-03.gif",
              "images/gem-04.gif",
            ],
            reviews: [{
              stars: 3,
              body: "I think this gem was just OK, could honestly use more shine, IMO.",
              author: "JimmyDean@example.org",
              createdOn: 1397490980837
            }, {
              stars: 4,
              body: "Any gem with 12 faces is for me!",
              author: "gemsRock@example.org",
              createdOn: 1397490980837
            }]
          }, {
            name: 'Zircon',
            description: "Zircon is our most coveted and sought after gem. You will pay much to be the proud owner of this gorgeous and high shine gem.",
            shine: 70,
            price: 1100,
            rarity: 2,
            color: '#000',
            faces: 6,
            images: [
              "images/gem-06.gif",
              "images/gem-07.gif",
              "images/gem-08.gif"
            ],
            reviews: [{
              stars: 1,
              body: "This gem is WAY too expensive for its rarity value.",
              author: "turtleguyy@example.org",
              createdOn: 1397490980837
            }, {
              stars: 1,
              body: "BBW: High Shine != High Quality.",
              author: "LouisW407@example.org",
              createdOn: 1397490980837
            }, {
              stars: 1,
              body: "Don't waste your rubles!",
              author: "nat@example.org",
              createdOn: 1397490980837
            }]
          }
        ];
      })();


      index.html

      
      <html ng-app="gemStore">
        <head>
          <link rel="stylesheet" type="text/css" href="bootstrap.min.css" />
          <script type="text/javascript" src="angular.min.js"></script>
          <script type="text/javascript" src="app.js"></script>
        </head>
        <body ng-controller="StoreController as store">
          <header>
            <h1 class="text-center">Flatlander Crafted Gems</h1>
            <h2 class="text-center">– an Angular store –</h2>
          </header>
          <div class="list-group">
            <div class="list-group-item" ng-repeat="product in store.products">
              <h3>{{product.name}} <em class="pull-right">{{product.price | currency}}</em></h3>
              <div ng-controller="GalleryController as gallery"  ng-show="product.images.length">
                <div class="img-wrap">
                  <img ng-src="{{product.images[gallery.current]}}" />
                </div>
                <ul class="img-thumbnails clearfix">
                  <li class="small-image pull-left thumbnail" ng-repeat="image in product.images">
                    <img ng-src="{{image}}" />
                  </li>
                </ul>
              </div>
              <section ng-controller="TabController as tab">
                <ul class="nav nav-pills">
                  <li ng-class="{ active:tab.isSet(1) }">
                    <a href="" ng-click="tab.setTab(1)">Description</a>
                  </li>
                  <li ng-class="{ active:tab.isSet(2) }">
                    <a href="" ng-click="tab.setTab(2)">Specs</a>
                  </li>
                  <li ng-class="{ active:tab.isSet(3) }">
                    <a href="" ng-click="tab.setTab(3)">Reviews</a>
                  </li>
                </ul>
                <div ng-show="tab.isSet(1)">
                  <h4>Description</h4>
                  <blockquote>{{product.description}}</blockquote>
                </div>
                <div ng-show="tab.isSet(2)">
                  <h4>Specs</h4>
                  <blockquote>Shine: {{product.shine}}</blockquote>
                </div>
                <div ng-show="tab.isSet(3)">
                  
                  <ul>
                    <h4>Reviews</h4>
                    <li ng-repeat="review in product.reviews">
                      <blockquote>
                        <strong>{{review.stars}} Stars</strong>
                        {{review.body}}
                        <cite class="clearfix">—{{review.author}}</cite>
                      </blockquote>
                    </li>
                  </ul>
      
                  
                  <form name="reviewForm" ng-controller="ReviewController as reviewCtrl"   ng-submit="reviewCtrl.addReview(product)" >
      
                    
                    <blockquote>
                      <strong>{{reviewCtrl.review.stars}} Stars</strong>
                      {{reviewCtrl.review.body}}
                      <cite class="clearfix">—{{reviewCtrl.review.author}}</cite>
                    </blockquote>
      
                    
                    <h4>Submit a Review</h4>
                    <fieldset class="form-group">
                      <select ng-model="reviewCtrl.review.stars" class="form-control" ng-options="stars for stars in [5,4,3,2,1]" title="Stars">
                        <option value="">Rate the Product</option>
                      </select>
                    </fieldset>
                    <fieldset class="form-group">
                      <textarea ng-model="reviewCtrl.review.body" class="form-control" placeholder="Write a short review of the product..." title="Review"></textarea>
                    </fieldset>
                    <fieldset class="form-group">
                      <input ng-model="reviewCtrl.review.author" type="email" class="form-control" placeholder="jimmyDean@example.org" title="Email" />
                    </fieldset>
                    <fieldset class="form-group">
                      <input type="submit" class="btn btn-primary pull-right" value="Submit Review" />
                    </fieldset>
                  </form>
                </div>
              </section>
            </div>
          </div>
        </body>
      </html>


      FORM VALIDATION

      index.html

      
      <html ng-app="gemStore">
        <head>
          <link rel="stylesheet" type="text/css" href="bootstrap.min.css" />
          <script type="text/javascript" src="angular.min.js"></script>
          <script type="text/javascript" src="app.js"></script>
        </head>
      
        <body ng-controller="StoreController as store">
          
          <header>
            <h1 class="text-center">Flatlander Crafted Gems</h1>
            <h2 class="text-center">– an Angular store –</h2>
          </header>
      
          
          <div class="list-group">
            
            <div class="list-group-item" ng-repeat="product in store.products">
              <h3>{{product.name}} <em class="pull-right">{{product.price | currency}}</em></h3>
      
              
              <div ng-controller="GalleryController as gallery"  ng-show="product.images.length">
                <div class="img-wrap">
                  <img ng-src="{{product.images[gallery.current]}}" />
                </div>
                <ul class="img-thumbnails clearfix">
                  <li class="small-image pull-left thumbnail" ng-repeat="image in product.images">
                    <img ng-src="{{image}}" />
                  </li>
                </ul>
              </div>
      
              
              <section ng-controller="TabController as tab">
                <ul class="nav nav-pills">
                  <li ng-class="{ active:tab.isSet(1) }">
                    <a href="" ng-click="tab.setTab(1)">Description</a>
                  </li>
                  <li ng-class="{ active:tab.isSet(2) }">
                    <a href="" ng-click="tab.setTab(2)">Specs</a>
                  </li>
                  <li ng-class="{ active:tab.isSet(3) }">
                    <a href="" ng-click="tab.setTab(3)">Reviews</a>
                  </li>
                </ul>
      
                
                <div ng-show="tab.isSet(1)">
                  <h4>Description</h4>
                  <blockquote>{{product.description}}</blockquote>
                </div>
      
                
                <div ng-show="tab.isSet(2)">
                  <h4>Specs</h4>
                  <blockquote>Shine: {{product.shine}}</blockquote>
                </div>
      
                
                <div ng-show="tab.isSet(3)">
                  
                  <ul>
                    <h4>Reviews</h4>
                    <li ng-repeat="review in product.reviews">
                      <blockquote>
                        <strong>{{review.stars}} Stars</strong>
                        {{review.body}}
                        <cite class="clearfix">—{{review.author}}</cite>
                      </blockquote>
                    </li>
                  </ul>
      
                  
                  <form name="reviewForm" ng-controller="ReviewController as reviewCtrl" ng-submit="reviewForm.$valid && reviewCtrl.addReview(product)" novalidate>
      
                    
                    <blockquote >
                      <strong>{{reviewCtrl.review.stars}} Stars</strong>
                      {{reviewCtrl.review.body}}
                      <cite class="clearfix">—{{reviewCtrl.review.author}}</cite>
                    </blockquote>
      
                    
                    <h4>Submit a Review</h4>
                    <fieldset class="form-group">
                      <select ng-model="reviewCtrl.review.stars" class="form-control" ng-options="stars for stars in [5,4,3,2,1]" title="Stars" required>
                        <option value="">Rate the Product</option>
                      </select>
                    </fieldset>
                    <fieldset class="form-group">
                      <textarea ng-model="reviewCtrl.review.body" class="form-control" placeholder="Write a short review of the product..." title="Review"></textarea>
                    </fieldset>
                    <fieldset class="form-group">
                      <input ng-model="reviewCtrl.review.author" type="email" class="form-control" placeholder="jimmyDean@example.org" title="Email"  required/>
                    </fieldset>
                    <fieldset class="form-group">
                      <input type="submit" class="btn btn-primary pull-right" value="Submit Review" />
                    </fieldset>
                  </form>
                </div>
      
              </section>
            </div>
      
          </div>
        </body>
      </html>




      FORM STYLING

      application.css

      .ng-invalid.ng-dirty{
        border-color:red
      }
      .ng-valid.ng-dirty{
        border-color:green
      }




      app.js

      (function() {
        var app = angular.module('gemStore', []);
      
        app.controller('StoreController', function() {
          this.products = gems;
        });
      
        app.controller("TabController", function() {
          this.tab = 1;
      
          this.isSet = function(checkTab) {
            return this.tab === checkTab;
          };
      
          this.setTab = function(setTab) {
            this.tab = setTab;
          };
        });
      
        app.controller('GalleryController', function(){
          this.current = 0;
      
          this.setCurrent = function(imageNumber){
            this.current = imageNumber || 0;
          };
        });
      
        app.controller("ReviewController", function(){
      
          this.review = {};
      
          this.addReview = function(product){
            this.review.createdOn = Date.now();
            product.reviews.push(this.review);
            this.review = {};
          };
        });
      
        var gems = [{
            name: 'Azurite',
            description: "Some gems have hidden qualities beyond their luster, beyond their shine... Azurite is one of those gems.",
            shine: 8,
            price: 110.50,
            rarity: 7,
            color: '#CCC',
            faces: 14,
            images: [
              "images/gem-02.gif",
              "images/gem-05.gif",
              "images/gem-09.gif"
            ],
            reviews: [{
              stars: 5,
              body: "I love this gem!",
              author: "joe@example.org",
              createdOn: 1397490980837
            }, {
              stars: 1,
              body: "This gem sucks.",
              author: "tim@example.org",
              createdOn: 1397490980837
            }]
          }, {
            name: 'Bloodstone',
            description: "Origin of the Bloodstone is unknown, hence its low value. It has a very high shine and 12 sides, however.",
            shine: 9,
            price: 22.90,
            rarity: 6,
            color: '#EEE',
            faces: 12,
            images: [
              "images/gem-01.gif",
              "images/gem-03.gif",
              "images/gem-04.gif",
            ],
            reviews: [{
              stars: 3,
              body: "I think this gem was just OK, could honestly use more shine, IMO.",
              author: "JimmyDean@example.org",
              createdOn: 1397490980837
            }, {
              stars: 4,
              body: "Any gem with 12 faces is for me!",
              author: "gemsRock@example.org",
              createdOn: 1397490980837
            }]
          }, {
            name: 'Zircon',
            description: "Zircon is our most coveted and sought after gem. You will pay much to be the proud owner of this gorgeous and high shine gem.",
            shine: 70,
            price: 1100,
            rarity: 2,
            color: '#000',
            faces: 6,
            images: [
              "images/gem-06.gif",
              "images/gem-07.gif",
              "images/gem-08.gif"
            ],
            reviews: [{
              stars: 1,
              body: "This gem is WAY too expensive for its rarity value.",
              author: "turtleguyy@example.org",
              createdOn: 1397490980837
            }, {
              stars: 1,
              body: "BBW: High Shine != High Quality.",
              author: "LouisW407@example.org",
              createdOn: 1397490980837
            }, {
              stars: 1,
              body: "Don't waste your rubles!",
              author: "nat@example.org",
              createdOn: 1397490980837
            }]
          }];
      })();
      

      index.html

      
      <html ng-app="gemStore">
        <head>
          <link rel="stylesheet" type="text/css" href="bootstrap.min.css" />
          <script type="text/javascript" src="angular.min.js"></script>
          <script type="text/javascript" src="app.js"></script>
        </head>
      
        <body ng-controller="StoreController as store">
          
          <header>
            <h1 class="text-center">Flatlander Crafted Gems</h1>
            <h2 class="text-center">– an Angular store –</h2>
          </header>
      
          
          <div class="list-group">
            
            <div class="list-group-item" ng-repeat="product in store.products">
              <h3>{{product.name}} <em class="pull-right">{{product.price | currency}}</em></h3>
      
              
              <div ng-controller="GalleryController as gallery"  ng-show="product.images.length">
                <div class="img-wrap">
                  <img ng-src="{{product.images[gallery.current]}}" />
                </div>
                <ul class="img-thumbnails clearfix">
                  <li class="small-image pull-left thumbnail" ng-repeat="image in product.images">
                    <img ng-src="{{image}}" />
                  </li>
                </ul>
              </div>
      
              
              <section ng-controller="TabController as tab">
                <ul class="nav nav-pills">
                  <li ng-class="{ active:tab.isSet(1) }">
                    <a href ng-click="tab.setTab(1)">Description</a>
                  </li>
                  <li ng-class="{ active:tab.isSet(2) }">
                    <a href ng-click="tab.setTab(2)">Specs</a>
                  </li>
                  <li ng-class="{ active:tab.isSet(3) }">
                    <a href ng-click="tab.setTab(3)">Reviews</a>
                  </li>
                </ul>
      
                
                <div ng-show="tab.isSet(1)">
                  <h4>Description</h4>
                  <blockquote>{{product.description}}</blockquote>
                </div>
      
                
                <div ng-show="tab.isSet(2)">
                  <h4>Specs</h4>
                  <blockquote>Shine: {{product.shine}}</blockquote>
                </div>
      
                
                <div ng-show="tab.isSet(3)">
                  
                  <ul>
                    <h4>Reviews</h4>
                    <li ng-repeat="review in product.reviews">
                      <blockquote>
                        <strong>{{review.stars}} Stars</strong>
                        {{review.body}}
                        <cite class="clearfix">—{{review.author}}+"on"+{{review.createdOn |date}}</cite>
                      </blockquote>
                    </li>
                  </ul>
      
                  
                  <form name="reviewForm" ng-controller="ReviewController as reviewCtrl" ng-submit="reviewCtrl.addReview(product)">
      
                    
                    <blockquote >
                      <strong>{{reviewCtrl.review.stars}} Stars</strong>
                      {{reviewCtrl.review.body}}
                      <cite class="clearfix">—{{reviewCtrl.review.author}}</cite>
                    </blockquote>
      
                    
                    <h4>Submit a Review</h4>
                    <fieldset class="form-group">
                      <select ng-model="reviewCtrl.review.stars" class="form-control" ng-options="stars for stars in [5,4,3,2,1]" title="Stars">
                        <option value>Rate the Product</option>
                      </select>
                    </fieldset>
                    <fieldset class="form-group">
                      <textarea ng-model="reviewCtrl.review.body" class="form-control" placeholder="Write a short review of the product..." title="Review"></textarea>
                    </fieldset>
                    <fieldset class="form-group">
                      <input ng-model="reviewCtrl.review.author" type="email" class="form-control" placeholder="jimmyDean@example.org" title="Email" />
                    </fieldset>
                    <fieldset class="form-group">
                      <input type="submit" class="btn btn-primary pull-right" value="Submit Review" />
                    </fieldset>
                  </form>
                </div>
      
              </section>
            </div>
      
          </div>
        </body>
      </html>



      Exercise 12 : REFACTORING DESCRIPTION TAB


      index.html

      
      <html ng-app="gemStore">
        <head>
          <link rel="stylesheet" type="text/css" href="bootstrap.min.css" />
          <script type="text/javascript" src="angular.min.js"></script>
          <script type="text/javascript" src="app.js"></script>
        </head>
      
        <body ng-controller="StoreController as store">
          
          <header>
            <h1 class="text-center">Flatlander Crafted Gems</h1>
            <h2 class="text-center">– an Angular store –</h2>
          </header>
      
          
          <div class="list-group">
            
            <div class="list-group-item" ng-repeat="product in store.products">
              <h3>{{product.name}} <em class="pull-right">{{product.price | currency}}</em></h3>
      
              
              <div ng-controller="GalleryController as gallery"  ng-show="product.images.length">
                <div class="img-wrap">
                  <img ng-src="{{product.images[gallery.current]}}" />
                </div>
                <ul class="img-thumbnails clearfix">
                  <li class="small-image pull-left thumbnail" ng-repeat="image in product.images">
                    <img ng-src="{{image}}" />
                  </li>
                </ul>
              </div>
      
              
              <section ng-controller="TabController as tab">
                <ul class="nav nav-pills">
                  <li ng-class="{ active:tab.isSet(1) }">
                    <a href ng-click="tab.setTab(1)">Description</a>
                  </li>
                  <li ng-class="{ active:tab.isSet(2) }">
                    <a href ng-click="tab.setTab(2)">Specs</a>
                  </li>
                  <li ng-class="{ active:tab.isSet(3) }">
                    <a href ng-click="tab.setTab(3)">Reviews</a>
                  </li>
                </ul>
      
                
           <div ng-show="tab.isSet(1)" ng-include = "'product-description.html'"></div>
      
                
                <div ng-show="tab.isSet(2)">
                  <h4>Specs</h4>
                  <ul class="list-unstyled">
                    <li>
                      <strong>Shine</strong>
                      : {{product.shine}}</li>
                    <li>
                      <strong>Faces</strong>
                      : {{product.faces}}</li>
                    <li>
                      <strong>Rarity</strong>
                      : {{product.rarity}}</li>
                    <li>
                      <strong>Color</strong>
                      : {{product.color}}</li>
                  </ul>
                </div>
      
                
                <div ng-show="tab.isSet(3)">
                  
                  <ul>
                    <h4>Reviews</h4>
                    <li ng-repeat="review in product.reviews">
                      <blockquote>
                        <strong>{{review.stars}} Stars</strong>
                        {{review.body}}
                        <cite class="clearfix">—{{review.author}}</cite>
                      </blockquote>
                    </li>  
                  </ul>
      
                  
                  <form name="reviewForm" ng-controller="ReviewController as reviewCtrl" ng-submit="reviewCtrl.addReview(product)">
      
                    
                    <blockquote >
                      <strong>{{reviewCtrl.review.stars}} Stars</strong>
                      {{reviewCtrl.review.body}}
                      <cite class="clearfix">—{{reviewCtrl.review.author}}</cite>
                    </blockquote>
      
                    
                    <h4>Submit a Review</h4>
                    <fieldset class="form-group">
                      <select ng-model="reviewCtrl.review.stars" class="form-control" ng-options="stars for stars in [5,4,3,2,1]" title="Stars">
                        <option value>Rate the Product</option>
                      </select>
                    </fieldset>
                    <fieldset class="form-group">
                      <textarea ng-model="reviewCtrl.review.body" class="form-control" placeholder="Write a short review of the product..." title="Review"></textarea>
                    </fieldset>
                    <fieldset class="form-group">
                      <input ng-model="reviewCtrl.review.author" type="email" class="form-control" placeholder="jimmyDean@example.org" title="Email" />
                    </fieldset>
                    <fieldset class="form-group">
                      <input type="submit" class="btn btn-primary pull-right" value="Submit Review" />
                    </fieldset>
                  </form>
                </div>
      
              </section>
            </div>
      
          </div>
        </body>
      </html>
      

      product-description.html

      
      
                  <h4>Description</h4>
                  <blockquote>{{product.description}}</blockquote>
       


      CREATING AN ELEMENT DIRECTIVE

      4.3 Creating an Element Directive


      app.js

      (function() {
        var app = angular.module('gemStore', []);
      
        app.controller('GalleryController', function(){
          this.current = 0;
          this.setCurrent = function(imageNumber){
            this.current = imageNumber || 0;
          };
        });
      
        app.controller('StoreController', function() {
          this.products = gems;
        });
      
        app.controller("TabController", function() {
          this.tab = 1;
      
          this.isSet = function(checkTab) {
            return this.tab === checkTab;
          };
      
          this.setTab = function(setTab) {
            this.tab = setTab;
          };
        });
      
        app.controller("ReviewController", function(){
      
          this.review = {};
      
          this.addReview = function(product){
            product.reviews.push(this.review);
            this.review = {};
          };
      
        });
      
        app.directive("productDescription",function(){
          return {
              restrict:'E',
              templateUrl:"product-description.html"
            };
        });
      
        var gems = [
          {
            name: 'Azurite',
            description: "Some gems have hidden qualities beyond their luster, beyond their shine... Azurite is one of those gems.",
            shine: 8,
            price: 110.50,
            rarity: 7,
            color: '#CCC',
            faces: 14,
            images: [
              "images/gem-02.gif",
              "images/gem-05.gif",
              "images/gem-09.gif"
            ],
            reviews: [{
              stars: 5,
              body: "I love this gem!",
              author: "joe@example.org"
            }, {
              stars: 1,
              body: "This gem sucks.",
              author: "tim@example.org"
            }]
          }, {
            name: 'Bloodstone',
            description: "Origin of the Bloodstone is unknown, hence its low value. It has a very high shine and 12 sides, however.",
            shine: 9,
            price: 22.90,
            rarity: 6,
            color: '#EEE',
            faces: 12,
            images: [
              "images/gem-01.gif",
              "images/gem-03.gif",
              "images/gem-04.gif"
            ],
            reviews: [{
              stars: 3,
              body: "I think this gem was just OK, could honestly use more shine, IMO.",
              author: "JimmyDean@example.org"
            }, {
              stars: 4,
              body: "Any gem with 12 faces is for me!",
              author: "gemsRock@example.org"
            }]
            }, {
              name: 'Zircon',
              description: "Zircon is our most coveted and sought after gem. You will pay much to be the proud owner of this gorgeous and high shine gem.",
              shine: 70,
              price: 1100,
              rarity: 2,
              color: '#000',
              faces: 6,
              images: [
                "images/gem-06.gif",
                "images/gem-07.gif",
                "images/gem-08.gif"
              ],
              reviews: [{
                stars: 1,
                body: "This gem is WAY too expensive for its rarity value.",
                author: "turtleguyy@example.org"
              }, {
                stars: 1,
                body: "BBW: High Shine != High Quality.",
                author: "LouisW407@example.org"
              }, {
                stars: 1,
                body: "Don't waste your rubles!",
                author: "nat@example.org"
              }]
          }
        ];
      })();
      

      index.html

      
      <html ng-app="gemStore">
        <head>
          <link rel="stylesheet" type="text/css" href="bootstrap.min.css" />
          <script type="text/javascript" src="angular.min.js"></script>
          <script type="text/javascript" src="app.js"></script>
        </head>
      
        <body ng-controller="StoreController as store">
          
          <header>
            <h1 class="text-center">Flatlander Crafted Gems</h1>
            <h2 class="text-center">– an Angular store –</h2>
          </header>
      
          
          <div class="list-group">
            
            <div class="list-group-item" ng-repeat="product in store.products">
              <h3>{{product.name}} <em class="pull-right">{{product.price | currency}}</em></h3>
      
              
              <div ng-controller="GalleryController as gallery"  ng-show="product.images.length">
                <div class="img-wrap">
                  <img ng-src="{{product.images[gallery.current]}}" />
                </div>
                <ul class="img-thumbnails clearfix">
                  <li class="small-image pull-left thumbnail" ng-repeat="image in product.images">
                    <img ng-src="{{image}}" />
                  </li>
                </ul>
              </div>
      
              
              <section ng-controller="TabController as tab">
                <ul class="nav nav-pills">
                  <li ng-class="{ active:tab.isSet(1) }">
                    <a href ng-click="tab.setTab(1)">Description</a>
                  </li>
                  <li ng-class="{ active:tab.isSet(2) }">
                    <a href ng-click="tab.setTab(2)">Specs</a>
                  </li>
                  <li ng-class="{ active:tab.isSet(3) }">
                    <a href ng-click="tab.setTab(3)">Reviews</a>
                  </li>
                </ul>
      
                
             
                <product-description ng-show="tab.isSet(1)" ></product-description>
      
                
                <div ng-show="tab.isSet(2)">
                  <h4>Specs</h4>
                  <ul class="list-unstyled">
                    <li>
                      <strong>Shine</strong>
                      : {{product.shine}}</li>
                    <li>
                      <strong>Faces</strong>
                      : {{product.faces}}</li>
                    <li>
                      <strong>Rarity</strong>
                      : {{product.rarity}}</li>
                    <li>
                      <strong>Color</strong>
                      : {{product.color}}</li>
                  </ul>
                </div>
      
                
                <div ng-show="tab.isSet(3)">
                  
                  <ul>
                    <h4>Reviews</h4>
                    <li ng-repeat="review in product.reviews">
                      <blockquote>
                        <strong>{{review.stars}} Stars</strong>
                        {{review.body}}
                        <cite class="clearfix">—{{review.author}}</cite>
                      </blockquote>
                    </li>
                  </ul>
      
                  
                  <form name="reviewForm" ng-controller="ReviewController as reviewCtrl" ng-submit="reviewCtrl.addReview(product)">
      
                    
                    <blockquote >
                      <strong>{{reviewCtrl.review.stars}} Stars</strong>
                      {{reviewCtrl.review.body}}
                      <cite class="clearfix">—{{reviewCtrl.review.author}}</cite>
                    </blockquote>
      
                    
                    <h4>Submit a Review</h4>
                    <fieldset class="form-group">
                      <select ng-model="reviewCtrl.review.stars" class="form-control" ng-options="stars for stars in [5,4,3,2,1]" title="Stars">
                        <option value>Rate the Product</option>
                      </select>
                    </fieldset>
                    <fieldset class="form-group">
                      <textarea ng-model="reviewCtrl.review.body" class="form-control" placeholder="Write a short review of the product..." title="Review"></textarea>
                    </fieldset>
                    <fieldset class="form-group">
                      <input ng-model="reviewCtrl.review.author" type="email" class="form-control" placeholder="jimmyDean@example.org" title="Email" />
                    </fieldset>
                    <fieldset class="form-group">
                      <input type="submit" class="btn btn-primary pull-right" value="Submit Review" />
                    </fieldset>
                  </form>
                </div>
              </section>
            </div>
          </div>
        </body>
      </html>


      4.4 Creating an Attribute Directive 


      index.html

      
      <html ng-app="gemStore">
        <head>
          <link rel="stylesheet" type="text/css" href="bootstrap.min.css" />
          <script type="text/javascript" src="angular.min.js"></script>
          <script type="text/javascript" src="app.js"></script>
        </head>
        <body ng-controller="StoreController as store">
          <header>
            <h1 class="text-center">Flatlander Crafted Gems</h1>
            <h2 class="text-center">– an Angular store –</h2>
          </header>
          <div class="list-group">
            <div class="list-group-item" ng-repeat="product in store.products">
              <h3>{{product.name}} <em class="pull-right">{{product.price | currency}}</em></h3>
              <div ng-controller="GalleryController as gallery"  ng-show="product.images.length">
                <div class="img-wrap">
                  <img ng-src="{{product.images[gallery.current]}}" />
                </div>
                <ul class="img-thumbnails clearfix">
                  <li class="small-image pull-left thumbnail" ng-repeat="image in product.images">
                    <img ng-src="{{image}}" />
                  </li>
                </ul>
              </div>
              <section ng-controller="TabController as tab">
                <ul class="nav nav-pills">
                  <li ng-class="{ active:tab.isSet(1) }">
                    <a href ng-click="tab.setTab(1)">Description</a>
                  </li>
                  <li ng-class="{ active:tab.isSet(2) }">
                    <a href ng-click="tab.setTab(2)">Specs</a>
                  </li>
                  <li ng-class="{ active:tab.isSet(3) }">
                    <a href ng-click="tab.setTab(3)">Reviews</a>
                  </li>
                </ul>
                <div ng-show="tab.isSet(1)" ng-include="product-description.html"></div>
      
                
                <div ng-show="tab.isSet(2)"  product-specs>
      
                </div>
      
                
                <product-reviews ng-show="tab.isSet(3)"></product-reviews>
              </section>
            </div>
          </div>
        </body>
      </html>
      

      product-specs.html

      <h4>Specs</h4>
                  <ul class="list-unstyled">
                    <li>
                      <strong>Shine</strong>
                      : {{product.shine}}</li>
                    <li>
                      <strong>Faces</strong>
                      : {{product.faces}}</li>
                    <li>
                      <strong>Rarity</strong>
                      : {{product.rarity}}</li>
                    <li>
                      <strong>Color</strong>
                      : {{product.color}}</li>
                  </ul> 
      

      app.js

      (function() {
        var app = angular.module('gemStore', []);
      
        app.controller('GalleryController', function(){
          this.current = 0;
          this.setCurrent = function(imageNumber){
            this.current = imageNumber || 0;
          };
        });
      
        app.controller('StoreController', function() {
          this.products = gems;
        });
      
        app.controller("TabController", function() {
          this.tab = 1;
      
          this.isSet = function(checkTab) {
            return this.tab === checkTab;
          };
      
          this.setTab = function(setTab) {
            this.tab = setTab;
          };
        });
      
        app.controller("ReviewController", function(){
      
          this.review = {};
      
          this.addReview = function(product){
            product.reviews.push(this.review);
            this.review = {};
          };
      
        });
      
        app.directive("productDescriptions", function() {
          return {
            restrict: 'E',
            templateUrl: "product-description.html"
          };
        });
      
        app.directive("productReviews", function() {
          return {
            restrict: 'E',
            templateUrl: "product-reviews.html"
          };
        });
      
        app.directive("productSpecs",function(){
          return {
             restrict:'A',
             templateUrl:"product-specs.html"
          };
          
        });
      
        var gems = [
          {
            name: 'Azurite',
            description: "Some gems have hidden qualities beyond their luster, beyond their shine... Azurite is one of those gems.",
            shine: 8,
            price: 110.50,
            rarity: 7,
            color: '#CCC',
            faces: 14,
            images: [
              "images/gem-02.gif",
              "images/gem-05.gif",
              "images/gem-09.gif"
            ],
            reviews: [{
              stars: 5,
              body: "I love this gem!",
              author: "joe@example.org"
            }, {
              stars: 1,
              body: "This gem sucks.",
              author: "tim@example.org"
            }]
          }, {
            name: 'Bloodstone',
            description: "Origin of the Bloodstone is unknown, hence its low value. It has a very high shine and 12 sides, however.",
            shine: 9,
            price: 22.90,
            rarity: 6,
            color: '#EEE',
            faces: 12,
            images: [
              "images/gem-01.gif",
              "images/gem-03.gif",
              "images/gem-04.gif"
            ],
            reviews: [{
              stars: 3,
              body: "I think this gem was just OK, could honestly use more shine, IMO.",
              author: "JimmyDean@example.org"
            }, {
              stars: 4,
              body: "Any gem with 12 faces is for me!",
              author: "gemsRock@example.org"
            }]
            }, {
              name: 'Zircon',
              description: "Zircon is our most coveted and sought after gem. You will pay much to be the proud owner of this gorgeous and high shine gem.",
              shine: 70,
              price: 1100,
              rarity: 2,
              color: '#000',
              faces: 6,
              images: [
                "images/gem-06.gif",
                "images/gem-07.gif",
                "images/gem-08.gif"
              ],
              reviews: [{
                stars: 1,
                body: "This gem is WAY too expensive for its rarity value.",
                author: "turtleguyy@example.org"
              }, {
                stars: 1,
                body: "BBW: High Shine != High Quality.",
                author: "LouisW407@example.org"
              }, {
                stars: 1,
                body: "Don't waste your rubles!",
                author: "nat@example.org"
              }]
          }
        ];
      })();
      _________________________________________________________________________________

      DIRECTIVE CONTROLLERS

      DC :EXERCISE 1

      app.js

      (function() {
        var app = angular.module('gemStore', []);
      
        app.controller('GalleryController', function(){
          this.current = 0;
          this.setCurrent = function(imageNumber){
            this.current = imageNumber || 0;
          };
        });
      
        app.controller('StoreController', function() {
          this.products = gems;
        });
      
      
          app.directive("productTabs",function(){
          return{
            restrict:'E',
            templateUrl:'product-tabs.html',
            controller: function() {
                  this.tab = 1;
                  this.isSet = function(checkTab) {
                     return this.tab === checkTab;
                   };
                  this.setTab = function(setTab) {
                      this.tab = setTab;
                   };
              },
            controllerAs:'tab'
        };
          });
      
        app.controller("ReviewController", function(){
      
          this.review = {};
      
          this.addReview = function(product){
            product.reviews.push(this.review);
            this.review = {};
          };
      
        });
      
        app.directive("productDescription", function() {
          return {
            restrict: 'E',
            templateUrl: "product-description.html"
          };
        });
      
        app.directive("productReviews", function() {
          return {
            restrict: 'E',
            templateUrl: "product-reviews.html"
          };
        });
      
        app.directive("productSpecs", function() {
          return {
            restrict:"A",
            templateUrl: "product-specs.html"
          };
        });
      
        var gems = [
          {
            name: 'Azurite',
            description: "Some gems have hidden qualities beyond their luster, beyond their shine... Azurite is one of those gems.",
            shine: 8,
            price: 110.50,
            rarity: 7,
            color: '#CCC',
            faces: 14,
            images: [
              "images/gem-02.gif",
              "images/gem-05.gif",
              "images/gem-09.gif"
            ],
            reviews: [{
              stars: 5,
              body: "I love this gem!",
              author: "joe@example.org"
            }, {
              stars: 1,
              body: "This gem sucks.",
              author: "tim@example.org"
            }]
          }, {
            name: 'Bloodstone',
            description: "Origin of the Bloodstone is unknown, hence its low value. It has a very high shine and 12 sides, however.",
            shine: 9,
            price: 22.90,
            rarity: 6,
            color: '#EEE',
            faces: 12,
            images: [
              "images/gem-01.gif",
              "images/gem-03.gif",
              "images/gem-04.gif"
            ],
            reviews: [{
              stars: 3,
              body: "I think this gem was just OK, could honestly use more shine, IMO.",
              author: "JimmyDean@example.org"
            }, {
              stars: 4,
              body: "Any gem with 12 faces is for me!",
              author: "gemsRock@example.org"
            }]
            }, {
              name: 'Zircon',
              description: "Zircon is our most coveted and sought after gem. You will pay much to be the proud owner of this gorgeous and high shine gem.",
              shine: 70,
              price: 1100,
              rarity: 2,
              color: '#000',
              faces: 6,
              images: [
                "images/gem-06.gif",
                "images/gem-07.gif",
                "images/gem-08.gif"
              ],
              reviews: [{
                stars: 1,
                body: "This gem is WAY too expensive for its rarity value.",
                author: "turtleguyy@example.org"
              }, {
                stars: 1,
                body: "BBW: High Shine != High Quality.",
                author: "LouisW407@example.org"
              }, {
                stars: 1,
                body: "Don't waste your rubles!",
                author: "nat@example.org"
              }]
          }
        ];
      })();
      

      index.html

      
      <html ng-app="gemStore">
        <head>
          <link rel="stylesheet" type="text/css" href="bootstrap.min.css" />
          <script type="text/javascript" src="angular.min.js"></script>
          <script type="text/javascript" src="app.js"></script>
        </head>
      
        <body ng-controller="StoreController as store">
          
          <header>
            <h1 class="text-center">Flatlander Crafted Gems</h1>
            <h2 class="text-center">– an Angular store –</h2>
          </header>
      
          
          <div class="list-group">
            
            <div class="list-group-item" ng-repeat="product in store.products">
              <h3>{{product.name}} <em class="pull-right">{{product.price | currency}}</em></h3>
      
              
              <div ng-controller="GalleryController as gallery"  ng-show="product.images.length">
                <div class="img-wrap">
                  <img ng-src="{{product.images[gallery.current]}}" />
                </div>
                <ul class="img-thumbnails clearfix">
                  <li class="small-image pull-left thumbnail" ng-repeat="image in product.images">
                    <img ng-src="{{image}}" />
                  </li>
                </ul>
              </div>
      
              
              <product-tabs></product-tabs>
            </div>
      
          </div>
        </body>
      </html>
      

      product-tabs.html

      <section >
                <ul class="nav nav-pills">
                  <li ng-class="{ active:tab.isSet(1) }">
                    <a href ng-click="tab.setTab(1)">Description</a>
                  </li>
                  <li ng-class="{ active:tab.isSet(2) }">
                    <a href ng-click="tab.setTab(2)">Specs</a>
                  </li>
                  <li ng-class="{ active:tab.isSet(3) }">
                    <a href ng-click="tab.setTab(3)">Reviews</a>
                  </li>
                </ul>
      
                
                <div ng-show="tab.isSet(1)" ng-include="'product-description.html'">
                </div>
      
                
                <div product-specs ng-show="tab.isSet(2)"></div>
      
                
                <product-reviews ng-show="tab.isSet(3)"></product-reviews>
      
              </section> 



      _______________________________________________________________________________

      4.7 Refactoring Product Gallery



      app.js

      (function() {
        var app = angular.module('gemStore', []);
      
        app.directive('productGallery',function(){
          return{
            restrict:'E',
            templateUrl:'product-gallery.html',
            controller: function(){
                this.current = 0;
               this.setCurrent = function(imageNumber){
               this.current = imageNumber || 0;
            };
            },
            controllerAs : 'gallery'
            
          };
        });
      
        app.controller('StoreController', function() {
          this.products = gems;
        });
      
        app.controller("ReviewController", function(){
      
          this.review = {};
      
          this.addReview = function(product){
            product.reviews.push(this.review);
            this.review = {};
          };
      
        });
      
        app.directive("productDescriptions", function() {
          return {
            restrict: 'E',
            templateUrl: "product-description.html"
          };
        });
      
        app.directive("productReviews", function() {
          return {
            restrict: 'E',
            templateUrl: "product-reviews.html"
          };
        });
      
        app.directive("productSpecs", function() {
          return {
            restrict:"A",
            templateUrl: "product-specs.html"
          };
        });
      
        app.directive("productTabs", function() {
          return {
            restrict: "E",
            templateUrl: "product-tabs.html",
            controller: function() {
              this.tab = 1;
      
              this.isSet = function(checkTab) {
                return this.tab === checkTab;
              };
      
              this.setTab = function(activeTab) {
                this.tab = activeTab;
              };
            },
            controllerAs: "tab"
          };
        });
      
        var gems = [
          {
            name: 'Azurite',
            description: "Some gems have hidden qualities beyond their luster, beyond their shine... Azurite is one of those gems.",
            shine: 8,
            price: 110.50,
            rarity: 7,
            color: '#CCC',
            faces: 14,
            images: [
              "images/gem-02.gif",
              "images/gem-05.gif",
              "images/gem-09.gif"
            ],
            reviews: [{
              stars: 5,
              body: "I love this gem!",
              author: "joe@example.org"
            }, {
              stars: 1,
              body: "This gem sucks.",
              author: "tim@example.org"
            }]
          }, {
            name: 'Bloodstone',
            description: "Origin of the Bloodstone is unknown, hence its low value. It has a very high shine and 12 sides, however.",
            shine: 9,
            price: 22.90,
            rarity: 6,
            color: '#EEE',
            faces: 12,
            images: [
              "images/gem-01.gif",
              "images/gem-03.gif",
              "images/gem-04.gif"
            ],
            reviews: [{
              stars: 3,
              body: "I think this gem was just OK, could honestly use more shine, IMO.",
              author: "JimmyDean@example.org"
            }, {
              stars: 4,
              body: "Any gem with 12 faces is for me!",
              author: "gemsRock@example.org"
            }]
            }, {
              name: 'Zircon',
              description: "Zircon is our most coveted and sought after gem. You will pay much to be the proud owner of this gorgeous and high shine gem.",
              shine: 70,
              price: 1100,
              rarity: 2,
              color: '#000',
              faces: 6,
              images: [
                "images/gem-06.gif",
                "images/gem-07.gif",
                "images/gem-08.gif"
              ],
              reviews: [{
                stars: 1,
                body: "This gem is WAY too expensive for its rarity value.",
                author: "turtleguyy@example.org"
              }, {
                stars: 1,
                body: "BBW: High Shine != High Quality.",
                author: "LouisW407@example.org"
              }, {
                stars: 1,
                body: "Don't waste your rubles!",
                author: "nat@example.org"
              }]
          }
        ];
      })();
      

      index.html

      
      <html ng-app="gemStore">
        <head>
          <link rel="stylesheet" type="text/css" href="bootstrap.min.css" />
          <script type="text/javascript" src="angular.min.js"></script>
          <script type="text/javascript" src="app.js"></script>
        </head>
      
        <body ng-controller="StoreController as store">
          
          <header>
            <h1 class="text-center">Flatlander Crafted Gems</h1>
            <h2 class="text-center">– an Angular store –</h2>
          </header>
      
          
          <div class="list-group">
            
            <div class="list-group-item" ng-repeat="product in store.products">
              <h3>{{product.name}} <em class="pull-right">{{product.price | currency}}</em></h3>
      
              
                <product-gallery></product-gallery>
      
              
              <product-tabs></product-tabs>
      
            </div>
          </div>
        </body>
      </html>
      

      product-gallery.html

      <div ng-show="product.images.length">
        <div class="img-wrap">
          <img ng-src="{{product.images[gallery.current]}}" />
        </div>
        <ul class="img-thumbnails clearfix">
          <li class="small-image pull-left thumbnail" ng-repeat="image in product.images">
            <img ng-src="{{image}}" />
          </li>
        </ul>
      </div> 

      _______________________________________________________________________________


      _______________________________________________________________________________

      5.2 Refactoring into a Module


      products.js

      (function() {
        var app = angular.module("store-directives",[]);
       
        app.directive("productDescription", function() {
          return {
            restrict: 'E',
            templateUrl: "product-description.html"
          };
        });
      
        app.directive("productReviews", function() {
          return {
            restrict: 'E',
            templateUrl: "product-reviews.html"
          };
        });
      
        app.directive("productSpecs", function() {
          return {
            restrict:"A",
            templateUrl: "product-specs.html"
          };
        });
      
        app.directive("productTabs", function() {
          return {
            restrict: "E",
            templateUrl: "product-tabs.html",
            controller: function() {
              this.tab = 1;
      
              this.isSet = function(checkTab) {
                return this.tab === checkTab;
              };
      
              this.setTab = function(activeTab) {
                this.tab = activeTab;
              };
            },
            controllerAs: "tab"
          };
        });
      
        app.directive("productGallery", function() {
          return {
            restrict: "E",
            templateUrl: "product-gallery.html",
            controller: function() {
              this.current = 0;
              this.setCurrent = function(imageNumber){
                this.current = imageNumber || 0;
              };
            },
            controllerAs: "gallery"
          };
        });
        
      })();
      

      app.js

      (function() {
        var app = angular.module('gemStore', ['store-directives']);
      
        app.controller('StoreController', function(){
          this.products = gems;
        });
      
        app.controller('ReviewController', function() {
          this.review = {};
      
          this.addReview = function(product) {
            product.reviews.push(this.review);
      
            this.review = {};
          };
        });
      
        
      
        var gems = [{
            name: 'Azurite',
            description: "Some gems have hidden qualities beyond their luster, beyond their shine... Azurite is one of those gems.",
            shine: 8,
            price: 110.50,
            rarity: 7,
            color: '#CCC',
            faces: 14,
            images: [
              "images/gem-02.gif",
              "images/gem-05.gif",
              "images/gem-09.gif"
            ],
            reviews: []
          }, {
            name: 'Bloodstone',
            description: "Origin of the Bloodstone is unknown, hence its low value. It has a very high shine and 12 sides, however.",
            shine: 9,
            price: 22.90,
            rarity: 6,
            color: '#EEE',
            faces: 12,
            images: [
              "images/gem-01.gif",
              "images/gem-03.gif",
              "images/gem-04.gif",
            ],
            reviews: []
          }, {
            name: 'Zircon',
            description: "Zircon is our most coveted and sought after gem. You will pay much to be the proud owner of this gorgeous and high shine gem.",
            shine: 70,
            price: 1100,
            rarity: 2,
            color: '#000',
            faces: 6,
            images: [
              "images/gem-06.gif",
              "images/gem-07.gif",
              "images/gem-08.gif"
            ],
            reviews: []
          }];
      })();
      

      index.html

      
      <html ng-app="gemStore">
        <head>
          <link rel="stylesheet" type="text/css" href="bootstrap.min.css" />
          <script type="text/javascript" src="angular.min.js"></script>
          <script type="text/javascript" src="app.js"></script>
           <script type="text/javascript" src="products.js"></script>
        </head>
      
        <body ng-controller="StoreController as store">
          
          <header>
            <h1 class="text-center">Flatlander Crafted Gems</h1>
            <h2 class="text-center">– an Angular store –</h2>
          </header>
      
          
          <div class="list-group">
            
            <div class="list-group-item" ng-repeat="product in store.products">
              <h3>{{product.name}} <em class="pull-right">{{product.price | currency}}</em></h3>
      
              
              <product-gallery></product-gallery>
      
              
              <product-tabs></product-tabs>
            </div>
      
          </div>
        </body>
      </html>

      _______________________________________________________________________________

      5.4 Built-in AngularJS Services

      app.js

      (function() {
        var app = angular.module('gemStore', ['store-directives']);
      
        app.controller('StoreController',['$http',function($http){
          var store = this;
          store.products = [];
          $http.get('/store-products.json').success(function(data){
            store.products = data;
          });
        }]);
      
        app.controller('ReviewController', function() {
          this.review = {};
      
          this.addReview = function(product) {
            product.reviews.push(this.review);
      
            this.review = {};
          };
        });
      })();

      ______________________________________________________


      1.2 The Beginning of All Routes


      js/app.js

      angular.module('NoteWrangler',['ngRoute'])
             .config(['$routeProvider',function($routeProvider){
               $routeProvider.when('/notes',{
                 templateUrl:'templates/pages/notes/index.html'
               });
               
             }]);
               
                
      

      index.html

      
      <html lang="en" ng-app="NoteWrangler">
      
        <head>
          <meta charset="utf-8">
          <title>Note Wrangler</title>
          <meta name="viewport" content="width=device-width, initial-scale=1">
          <link rel="stylesheet" href="css/application.css" />
        </head>
      
        <body>
          <div class="nav-wrapper has-dropdown">
            <div class="nav-content">
              <div class="wrapper">
                <div class="nav-content-layout">
                  <div class="nav-list">
      
                    <a href="#/"
                    class="list-item"
                    ng-click="selected = 'notes'"
                    ng-class="{'active': selected == 'notes'}"> Notes </a>
      
                    <a href="#/users"
                    class="list-item"
                    ng-click="selected = 'users'"
                    ng-class="{'active': selected == 'users'}"> Users </a>
      
                  </div>
                </div>
              </div>
            </div>
          </div>
      
          <div class="hero-wrapper">
            <div class="hero-content">
              <div class="hero"></div>
            </div>
          </div>
      
          <div class="main-wrapper">
            <div ng-view></div>
          </div>
      
          
          <script src="./js/vendor/jquery.js"></script>
          <script src="./js/vendor/angular.js"></script>
          <script src="./js/vendor/angular-route.js"></script>
      
          <script src="./js/app.js"></script>
      
          
          <script src="./js/controllers/notes-create-controller.js"></script>
          <script src="./js/controllers/notes-edit-controller.js"></script>
          <script src="./js/controllers/notes-index-controller.js"></script>
          <script src="./js/controllers/notes-show-controller.js"></script>
          <script src="./js/controllers/users-index-controller.js"></script>
          <script src="./js/controllers/users-show-controller.js"></script>
      
      
        </body>
      </html>

      1.4 A New Route and a Root Route 


      js/app.js

      angular.module('NoteWrangler', ['ngRoute'])
      .config(['$routeProvider', function($routeProvider) {
        $routeProvider
          .when('/notes/new',{
          templateUrl:'templates/pages/notes/edit.html'
        }).when('/',{
          redirectTo:'/users'
        })
          .when('/notes', {
            templateUrl: 'templates/pages/notes/index.html'
          })
          .when('/users', {
            templateUrl: 'templates/pages/users/index.html'
          }).otherwise({
          redirectTo:'/notes'
        })
          ;
      
      }]);

      _________________________________________________________________________________

      llama.js

      var newLlamaRecruit = {
        llamaOne: 'Larry Llama'
      };
      
      $http({
        method:'POST',
        url:'/llamas.json',
        data: newLlamaRecruit
       });

      1.9 Inside Route Controller


      js/app.js

      angular.module('NoteWrangler', ['ngRoute'])
      .config(['$routeProvider', function($routeProvider) {
        $routeProvider
          .when('/', {
            redirectTo: '/users'
          })
          .when('/notes', {
            templateUrl: 'templates/pages/notes/index.html',
           controller: function($http) {
               var donkey = this; // closes over 'this'
               $http({method: 'GET', url: '/notes'}).success(function(data) {
                donkey.notes = data;
                  });
               },
        controllerAs: 'notesCtrl'
          })
          .when('/users', {
            templateUrl: 'templates/pages/users/index.html'
          })
          .when('/notes/new', {
            templateUrl: 'templates/pages/notes/edit.html'
          })
          .otherwise({
            redirectTo: '/notes'
          });
      }]);


       
         
           

      Notes


      _________________________________________________________________________________

      1.10 Outside Controller

      app/js/app.js

      angular.module('NoteWrangler', ['ngRoute'])
      .config(['$routeProvider', function($routeProvider) {
        $routeProvider
          .when('/', {
            redirectTo: '/users'
          })
          .when('/notes', {
            templateUrl: 'templates/pages/notes/index.html',
            controller: function($http){
              var controller = this;
              $http({method: 'GET', url: '/notes'}).success(function(data){
                controller.notes = data;
              });
            },
            controllerAs: 'notesCtrl'
          })
          .when('/users', {
            templateUrl: 'templates/pages/users/index.html'
          })
          .when('/notes/new', {
            templateUrl: 'templates/pages/notes/edit.html',
            controller :'NotesCreateController',
            controllerAs:'note'
      
          })
          .otherwise({
            redirectTo: '/notes'
          });
      }]);
      

      app/templates/pages/notes/new.html

      <div class="new-note">
        <div class="new-note-container">
          <form class="form">
            <fieldset>
              <label for="title">Title</label>
              <input name="title"  ng-model ="note.title"/>
            </fieldset>
      
            <fieldset>
              <label for="description">Description</label>
              <textarea name="description" ng-model="note.description"></textarea>
            </fieldset>
      
            <fieldset>
              <label for="content">Content</label>
              <textarea name="content" ng-model ="note.content" ></textarea>
            </fieldset>
      
            <button class="btn" ng-click= "note.saveNote(note)">Save</button>
          </form>
        </div>
      </div>
      _________________________________________________________________________________



      app/js/notes-show-controller.js

      angular.module('NoteWrangler')
      .controller('NotesShowController', ['$http','$routeParams',function($http,$routeParams) {
      var notes = this;
        $http({method:'GET',
            url: '/notes/' + $routeParams.id}).success(function(data){
             notes.note  = data;
      });
      }]);

      _________________________________________________________________________________

      2.3 Inline Controller & $scope


      js/directives/nw-card.js

      angular.module('NoteWrangler').directive('nwCard', [function() {
        return {
          restrict: 'E',
          templateUrl: 'templates/directives/nw-card.html',
          controller: function($scope) {
            $scope.header = 'Note Title';
            $scope.description = 'A lovely note description.';
          }
        };
      }]);
      

      templates/directives/nw-card.html

      <div class="card" title="{{header}}">
        <h2 class="h3">{{header}}</h2>
        <p>{{description}}</p>
      </div>

      _________________________________________________________________________________

      js/controllers/notes-index-controller.js

      angular.module('NoteWrangler')
      .controller('NotesIndexController', ['$http','$scope', function($http,$scope) {
      
      
        $http({method: 'GET', url: '/notes'}).success(function(data) {
          $scope.notes = data;
        });
      }]);
      

      js/routes.js

      angular.module('NoteWrangler', ['ngRoute'])
      .config(['$routeProvider', function($routeProvider) {
        $routeProvider
          .when('/', {
            redirectTo: '/users'
          })
          .when('/notes', {
            templateUrl: 'templates/pages/notes/index.html',
            controller: 'NotesIndexController',
          })
          .when('/users', {
            templateUrl: 'templates/pages/users/index.html'
          })
          .when('/notes/new', {
            templateUrl: 'templates/pages/notes/edit.html',
            controller: 'NotesCreateController'
          })
          .when('/notes/:id', {
            templateUrl: 'templates/pages/notes/show.html',
            controller: 'NotesShowController'
          })
          .otherwise({
            redirectTo: '/notes'
          });
      }]);
      

      templates/pages/notes/index.html

      <div class="note-wrapper">
        <div class="note-content">
          <div class="notes-header">
            <h1 title="Notes">Notes</h1>
          </div>
      
          <div class="note-wrapper">
            <a class="card-notes" ng-repeat="note in notes">
              <nw-card></nw-card>
            </a>
          </div>
      
        </div>
      </div>
      

      2.7 Setting on Scope



      angular.module('NoteWrangler', [])
      .directive("nwCard", function() {
        return {
          restrict: "E",
          templateUrl: "templates/directives/nw-card.html",
          controller: function($scope) {
            $scope.title = 'Space Llamas';
          }
        }
      });


      _________________________________________________________________________________

      2.8 A Flexible Card Directive

      nw-card.js

      angular.module('NoteWrangler')
      .directive('nwCard', function() {
        return {
          restrict: 'E',
          templateUrl: 'templates/directives/nw-card.html',
          scope:{
            header:"=",
            description :"="
          }
        };
      });
      

      nw-card.html

      <div class="card" title="{{header}}">
        <h2 class="h3">{{header}}</h2>
        <p>{{description}}</p>
      </div>

      _________________________________________________________________________________


      2.9 Making Isolation Work for You


      notes/index.html

      <div class="note-wrapper">
        <div class="note-content">
          <div class="notes-header">
            <h1 title="Notes">Notes</h1>
          </div>
          <div class="note-wrapper">
            <a class="card-notes" ng-repeat="note in notes" ng-href="#/notes/{{note.id}}">
              <nw-card header="note.title" description="note.description"></nw-card>
            </a>
          </div>
        </div>
      </div>
      

      users/index.html

      <div class="users-wrapper">
        <h1>Users</h1>
      
        <div class="users-wrapper">
          <a class="card-users" ng-repeat="user in users">
            <nw-card header ="user.name" description="user.bio"></nw-card>
          </a>
        </div>
      </div>

      _________________________________________________________________________________


      2.12 Style the Tweeted Note



      js/directives/nw-card.js


      angular.module('NoteWrangler')
      .directive('nwCard', function() {
        return {
          restrict: 'E',
          templateUrl: './templates/directives/nw-card.html',
          scope: {
            header: '=',
            description: '=',
            tweeted: '='
          },
          link: function(scope,element){
                if(scope.tweeted) {
                   element.addClass('tweeted');
                }
            
          }
          
        };
      });

      SS


      3.2 A Factory Recipe I 250 PTS

      js/services/note.js


      angular.module('NoteWrangler').factory("Note",[function NoteFactory() {
                                  
       }])
      
      ;


      3.3 A Factory Recipe II 



      js/services/note.js

      angular.module('NoteWrangler')
      .factory('Note', ['$http',function NoteFactory($http) {
      return  {
          all:function(){
            return   $http({method: 'GET', 
                    url: '/notes'});
         }
         };
      }]);
      

      js/controllers/notes-index-controller.js

      angular.module('NoteWrangler')
      .controller('NotesIndexController', ['$scope', 'Note', function($scope, Note) {
        Note.all().success(function(data){
          $scope.notes = data;
        });
      }]);


      3.5 A Tweetable Service








      3.8 Configurable Bits Need a Provider


      js/services/tweetable.js

      angular.module('NoteWrangler')
      .provider('Tweetable', function TweetableProvider() {
        var characterLength = 144;
      
        this.setLength = function(maxLength) {
          characterLength = maxLength;
        };
      
        this.$get = function($http) {
          return function(potentialTweet) {
            return $http({
              method: 'POST',
              url: 'http://gentle-spire-1153.herokuapp.com/tweet',
              data: {
                description: potentialTweet,
                maxLength: characterLength
              }
            });
          };
        };
      });



      3.9 Configuring the Tweet Length


      js/app.js

      angular.module('NoteWrangler', ['ngRoute'])
        .config(function(TweetableProvider){
        TweetableProvider.setLength(40);
        
      })
      ;
      
      



      3.11 $resource Refactor



      js/services/note.js

      angular.module('NoteWrangler')
      .factory('Note', ['$resource', function NoteFactory($resource) {
        return $resource("/notes",{},{});
      
      }]);
      

      js/app.js

      angular.module('NoteWrangler', ['ngRoute','ngResource'])
      .config(function(TweetableProvider) {
        TweetableProvider.setLength(144);
      });
      

      index.html

      
      <html lang="en" ng-app="NoteWrangler">
      
        <head>
          <meta charset="utf-8">
          <title>Note Wrangler</title>
          <meta name="viewport" content="width=device-width, initial-scale=1">
          <link rel="stylesheet" href="css/application.css" />
        </head>
      
        <body>
          <div class="nav-wrapper has-dropdown">
            <div class="nav-content">
              <div class="wrapper">
                <div class="nav-content-layout">
                  <div class="nav-list">
                    <a href="#/notes"
                    class="list-item"
                    ng-click="selected = 'notes'"
                    ng-class="{'active': selected == 'notes'}"> Notes </a>
      
                    <a href="#/users"
                    class="list-item"
                    ng-click="selected = 'users'"
                    ng-class="{'active': selected == 'users'}"> Users </a>
                  </div>
                </div>
              </div>
            </div>
          </div>
      
          <div class="hero-wrapper">
            <div class="hero-content">
              <div class="hero"></div>
            </div>
          </div>
      
          <div class="main-wrapper">
            <div ng-view></div>
          </div>
      
          
          <script src="./js/vendor/jquery.js"></script>
          <script src="./js/vendor/angular.js"></script>
          <script src="./js/vendor/angular-route.js"></script>
           <script src="./js/vendor/angular-resource.js"></script>
      
          
          <script src="./js/app.js"></script>
          <script src="./js/routes.js"></script>
      
          
          <script src="./js/controllers/notes-create-controller.js"></script>
          <script src="./js/controllers/notes-edit-controller.js"></script>
          <script src="./js/controllers/notes-index-controller.js"></script>
          <script src="./js/controllers/notes-show-controller.js"></script>
          <script src="./js/controllers/users-index-controller.js"></script>
          <script src="./js/controllers/users-show-controller.js"></script>
      
          
          <script src="./js/directives/nw-card.js"></script>
      
          
          <script src="./js/services/note.js"></script>
          <script src="./js/services/tweetable.js"></script>
      
        </body>
      </html>

      ______________________________________________________


      3.12 Using a $resource-ful Note Service



      Instead of calling the all() method of Note, we want to assign $scope.notes the value returned from the query() method of Note.
      $scope.notes = Note.query();
      • js/controllers/notes-index-controller.js

        angular.module('NoteWrangler')
        .controller('NotesIndexController', ['$scope', 'Note', 'Tweetable', function($scope, Note, Tweetable) {
          $scope.notes = Note.query();
        
          $scope.tweetThatNote = function(noteToTweet) {
            Tweetable(noteToTweet).success(function(status) {
              console.log(status);
            });
          };
        }]);

      ______________________________________________________


      3.13 A Custom Method for Our Note $resource 













      No comments:

      Post a Comment