Search

Categories

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Send mail to the author(s) E-mail

# Friday, 12 December 2014

http://www.ndcvideos.com/#/app/video/2861

@christianweyer

https://github.com/ChristianWeyer/myProducts-End-to-End – Big example.  Cordova too.  Uses TypeScript!

Easy way to do “Write once, deploy anywhere applications” like uber.

| | # 
( AngularJS | MVC )

http://www.ndcvideos.com/#/app/video/3061

http://www.melvicorp.com/downloads.html – Source code

image
Talking about a hybrid application – some Angular and some MVC

Uses routing in both frameworks, so some is MVC and some in ng.

Back button works perfectly

| | # 
# Wednesday, 10 December 2014

From ndc in London the second day of Training by Scott Allen.  He is expecting to deliver another Pluralsight course at the end of Jan 2015.  Possibly using https://github.com/OdeToCode/ngplaybook (scotta)


image

Writing notes a week after the event.  Source code is on https://github.com/OdeToCode/ngclass and cloned in c:\dev\ngclass

  • Module
  • Controller – really a ViewModel
  • Service – logic in here (Singletons)
  • Directive
  • Filter

Concepts covered

  • anchorscroll
  • 5 different ways to create a service
  • Yeoman – scaffolding engine
  • Jasmine – testing framework
  • Karma – test runner

**next step would be to replay the course going through notes and github checkins.  Possibly wait until end of Jan for next Pluralsight course.

This deserves serious time if going to dev applications in ng!

| | # 
# Tuesday, 02 December 2014

Working on a angular example and building it up.

https://github.com/OdeToCode/ngclass

image
End of day 1:  Increment/decrement good – databinding

image
Validation great and all databound

image
Filtering and sorting.  Filtering great as databinding

| | # 
# Thursday, 27 November 2014

 

  • View – just markup/view logic
  • Directives – eg ng-repeat,
  • Controller – eg code inside MainController which is linked via ng-controller
  • Services – reusable code

Countdown

setTimeout is a js function to do something in x ms

setContinue will continue to invoke every x ms

angular provides a service which wraps these funcitons $timeout and $interval.

Good to use theses services

  • Unit testable
  • Databinding issues

$http is a service.. but needs .get
$interval is a service.. but doesn’t need a .

5:30 of 8:50

var app = angular.module('my-app', []); // Injecting in the services we need? var MainController = function($scope, $http, $interval) { var onUserComplete = function(response) { $scope.user = response.data; // Service - More of an object API $http.get($scope.user.repos_url) .then(onRepos, onError) }; var onRepos = function(response) { $scope.repos = response.data; } var onError = function(reason) { $scope.error = "Could not fetch the data"; }; var decrementCountdown = function() { $scope.countdown --; if ($scope.countdown < 1) { $scope.search($scope.username); } } var startCountdown = function() { // Service - Function - can directly invoke it $interval(decrementCountdown, 1000, $scope.countdown); } $scope.search = function(username) { $http.get("https://api.github.com/users/" + username) .then(onUserComplete, onError); }; $scope.username = "angular" $scope.message = "Github Viewer"; $scope.repoSortOrder = "-stargazers_count"; $scope.countdown = 5; startCountdown(); } app.controller("MainController", MainController);

HTML:

<!DOCTYPE html> <html ng-app="my-app"> <head> <script data-require="angular.js@*" data-semver="1.3.1" src="//code.angularjs.org/1.3.1/angular.js"></script> <link rel="stylesheet" href="style.css" /> <script src="script.js"></script> </head> <body ng-controller="MainController"> <h1>{{message}}</h1> <div>{{error}}</div> {{ countdown }} <form name="searchUser" ng-submit="search(username)"> <!-- required validation--> <input type="search" required placeholder="username to find" ng-model="username" /> <input type="submit" value="Search" /> </form> <div ng-include="'userdetails.html'" ng-show="user"></div> </body> </html>

Build your own Services

  • resuable logic
  • shared data (eg sharing between controllers)
  • manage complexity (in a controller)

Many different ways to register a service with Angular

// angular is in the global namespace, no dependencies for this module var app = angular.module('githubViewer', []); // Injecting in the services we need? var MainController = function( $scope, github, $interval, $log, $anchorScroll, $location) { var onUserComplete = function(data) { $scope.user = data; // Service - More of an object API github.getRepos($scope.user).then(onRepos, onError) }; var onRepos = function(data) { $scope.repos = data; $location.hash("userDetails"); $anchorScroll(); } var onError = function(reason) { $scope.error = "Could not fetch the data"; }; var decrementCountdown = function() { $scope.countdown --; if ($scope.countdown < 1) { $scope.search($scope.username); } } var countdownInterval = null; var startCountdown = function() { // Service - Function - can directly invoke it countdownInterval = $interval(decrementCountdown, 1000, $scope.countdown); } $scope.search = function(username) { // In developer tools can see output $log.info("Searching for " + username); github.getUser(username).then(onUserComplete, onError); if(countdownInterval) { $interval.cancel(countdownInterval); // Blanking out the coundown number $scope.countdown = null; } }; $scope.username = "angular" $scope.message = "Github Viewer"; $scope.repoSortOrder = "-stargazers_count"; $scope.countdown = 5; startCountdown(); } app.controller("MainController", MainController);

HTML

<!DOCTYPE html> <html ng-app="githubViewer"> <head> <script data-require="angular.js@*" data-semver="1.3.1" src="//code.angularjs.org/1.3.1/angular.js"></script> <link rel="stylesheet" href="style.css" /> <script src="script.js"></script> <script src="github.js"></script> </head> <body ng-controller="MainController"> <h1>{{message}}</h1> <div>{{error}}</div> {{ countdown }} <form name="searchUser" ng-submit="search(username)"> <!-- required validation--> <input type="search" required placeholder="username to find" ng-model="username" /> <input type="submit" value="Search" /> </form> <div ng-include="'userdetails.html'" ng-show="user"></div> </body> </html>

github.js service:

(function() { // revealing module pattern var github = function($http) { var getUser = function(username) { // when getUser is called, they are going to get back a promise return $http.get("https://api.github.com/users/" + username) .then(function(response) { // as this is in .then, this is returned as a promise/callback return response.data; }); }; var getRepos = function(user){ return $http.get(user.repos_url) .then(function(response) { return response.data; }); }; return { getUser: getUser, getRepos: getRepos }; }; var module = angular.module("githubViewer"); module.factory("github", github); }());
| | # 

depends on angular-route.js, ng-route, and configure $routeProvider

default.html will become a layour/shell view – menu and footer

  • index.html (shell)
  • main.html (searching)
  • user.html (user details)
  • repo.html (repo details)

Idea is: **done modules in wrong order.. come back to this**

| | # 
# Wednesday, 26 November 2014

https://api.github.com/users/angular

ng-click and ng-submit

<body ng-controller="MainController"> <h1>{{message}}</h1> <div>{{error}}</div> {{ username }} <form name="searchUser"> <!-- push the username into the $scope --> <input type="search" placeholder="username to find" ng-model="username" /> <input type="submit" value="Search" ng-click="search(username)" /> </form> <div> <h2>{{ user.name }}</h2> <img ng-src="{{user.avatar_url}}" title="{{user.name}}" /> </div> </body>

then

var app = angular.module('my-app', []); var MainController = function($scope, $http) { var onUserComplete = function(response) { $scope.user = response.data; }; var onError = function(reason) { $scope.error = "Could not fetch the user"; }; $scope.search = function(username) { $http.get("https://api.github.com/users/" + username) .then(onUserComplete, onError); }; $scope.username = "angular" $scope.message = "Github Viewer"; } app.controller("MainController", ["$scope", "$http", MainController]);

image

HTML Validation

<!-- using ng-submit so can do validation --> <form name="searchUser" ng-submit="search(username)"> <!-- required validation--> <input type="search" required placeholder="username to find" ng-model="username" /> <input type="submit" value="Search" /> </form>

image

ng-repeat

https://api.github.com/users/angular/repos 
image
<table> <thead> <tr> <th>Name</th> <th>Stars</th> <th>Language</th> </tr> </thead> <!-- ng-repeat is like a foreach loop --> <tbody> <tr ng-repeat="repo in repos"> <td>{{repo.name}}</td> <!-- number is a filter --> <td>{{repo.stargazers_count | number}}</td> <td>{{repo.language}}</td> </tr> </tbody> </table>
and

var onUserComplete = function(response) { $scope.user = response.data; $http.get($scope.user.repos_url) .then(onRepos, onError) }; var onRepos = function(response) { $scope.repos = response.data; }

When the user has come back from github, do another call to get the repo’s, then put that into scope.

Filters

eg currency, date, filter (search), json (good for debugging), limitTo (eg take), lowercase, uppercase, orderBy

image

Order: <select ng-model="repoSortOrder"> <option value="+name">Name</option> <option value="-stargazers_count">Stars</option> <option value="+language">Language</option> </select> <table> <thead> <tr> <th>Name</th> <th>Stars</th> <th>Language</th> </tr> </thead> <!-- orderyBy minus is descending sort order --> <tbody> <tr ng-repeat="repo in repos | orderBy:repoSortOrder"> <td>{{repo.name}}</td> <!-- number is a filter --> <td>{{repo.stargazers_count | number}}</td> <td>{{repo.language}}</td> </tr> </tbody> </table>
$scope.username = "angular" $scope.message = "Github Viewer"; $scope.repoSortOrder = "-stargazers_count";

ng-show ng-hide ng-include

image

<!-- show if we do have a user - a string can be 'true'.. ie undefined is false --> <div ng-show="user"> <h2>{{ user.name }}</h2> <img ng-src="{{user.avatar_url}}" title="{{user.name}}" width="80" height="80" />Order: <select ng-model="repoSortOrder"> <option value="+name">Name</option> <option value="-stargazers_count">Stars</option> <option value="+language">Language</option> </select> </div> <!-- hide this if we don't have a user --> <table ng-hide="!user"> <thead> <tr> <th>Name</th> <th>Stars</th> <th>Language</th> </tr> </thead>
<!-- using ng-submit so can do validation --> <form name="searchUser" ng-submit="search(username)"> <!-- required validation--> <input type="search" required placeholder="username to find" ng-model="username" /> <input type="submit" value="Search" /> </form> <div ng-include="'userdetails.html'" ng-show="user"></div>

Directives

used ng-click

ng-mouseover, ng-doubleclick, ng-keypress

customdirectives eg dragndrop, bootstrap widgets

| | # 
# Monday, 24 November 2014

$scope – dollar is a sign that the component is angular eg attached model to $scope

4:17 of ControllerBasics

image
Not defined the controller function yet.

http://plnkr.co/edit/c9Ze2H89FGa4eEdeO72N?p=preview

image

 

var app = angular.module('my-app', [], function() { }) app.controller('MainController', function($scope) { // Object literal syntax var person = { firstName: "Scott", lastName: "Allen", imageSrc: "http://odetocode.com/Images/scott_allen_2.jpg" }; $scope.message = "Hello, Angular!"; $scope.person = person; })

then:

<html ng-app="my-app"> <head> <script data-require="angular.js@*" data-semver="1.3.1" src="//code.angularjs.org/1.3.1/angular.js"></script> <link rel="stylesheet" href="style.css" /> <script src="script.js"></script> </head> <body ng-controller="MainController"> <h1>{{message}}</h1> Length of title: {{message.length}} <div> <div>First name: {{person.firstName}}</div> <div>Last name: {{person.lastName}}</div> <div> <!-- Once angular is up and running and evaluated the expression it will load --> <img ng-src="{{person.imageSrc}}" title="{{person.firstName}} {{person.lastName}}" /> </div> </div> </body> </html>

$http Service

var app = angular.module('my-app', [], function() { }) app.controller('MainController', function($scope, $http) { var onUserComplete = function(response) { $scope.user = response.data; }; var onError = function(reason) { $scope.error = "Could not fetch the user"; }; $http.get("https://api.github.com/users/robconery") // a promise .then(onUserComplete, onError); $scope.message = "Hello, Angular!"; })

or

// angular is in the global namespace var app = angular.module('my-app', []); var MainController = function($scope, $http) { var onUserComplete = function(response) { $scope.user = response.data; }; var onError = function(reason) { $scope.error = "Could not fetch the user"; }; $http.get("https://api.github.com/users/robconery") // a promise .then(onUserComplete, onError); $scope.message = "Hello, Angular!"; } //app.controller("MainController", MainController); // For minification need to tell Angular explicitly it's dependencies app.controller("MainController", ["$scope", "$http", MainController]);

I prefer this syntax.

<!DOCTYPE html> <html ng-app="my-app"> <head> <script data-require="angular.js@*" data-semver="1.3.1" src="//code.angularjs.org/1.3.1/angular.js"></script> <link rel="stylesheet" href="style.css" /> <script src="script.js"></script> </head> <body ng-controller="MainController"> <h1>{{message}}</h1> <div> {{error}} </div> <div> <div> User: {{user.name}} </div> <div> Location: {{user.location}} </div> <div> <img ng-src="{{user.avatar_url}}" title="{{user.name}}" /> </div> </div> </body> </html>
Next module on Views and Directives..

| | # 

Google project, now OS

builtwith.angular.js

youtube, msnbc

plnkr.co

image

<ng-app> – application directive

<body ng-app> <h1>Hello Plunker!</h1> {{ 843 / 42}} </body>

Binding expression – double {{

Monokai editor, and no autorefresh in editor.

image
F12 for developer tools in chrome, and then right click to clear the console messages.

JavaScript Patterns

  • Functions as abstractions
  • Functions to build modules
  • Functions to avoid global variables
var work = function() { console.log("working hard!"); }; //work();

Then

var work = function() { console.log("working hard!"); }; // Generic function which logs, and does error handling // Functions as abstractions var doWork = function(f) { console.log("starting"); try { f(); } catch(ex) { console.log(ex); } console.log("end"); }; // Pass the varibla work (which is a function) // into doWork which executes the first function doWork(work);

Functions as Modules

// Revealing module pattern var createWorker = function() { // Private implementation details var workCount = 0; var task1 = function() { workCount += 1; console.log("task1 " + workCount); }; var task2 = function() { workCount += 1; console.log("task2 " + workCount); }; return { // Public API // Job1 points to task1 job1: task1, job2: task2 }; } // Global variable (bad) var worker = createWorker(); worker.job1(); worker.job2(); worker.job2(); worker.job2();

Global Variables

variables defined outside of any other function.  createWorker and worker above

In JS they are evil!

var program = function() { // Revealing module pattern var createWorker = function() { // Private implementation details var workCount = 0; var task1 = function() { workCount += 1; console.log("task1 " + workCount); }; var task2 = function() { workCount += 1; console.log("task2 " + workCount); }; return { // Public API // Job1 points to task1 job1: task1, job2: task2 }; } // Global variable (bad) var worker = createWorker(); worker.job1(); worker.job2(); worker.job2(); worker.job2(); } program();

1 global variable now.

// Immediately invoked fucntion expression "iffy" // Anonymous function (function() { // Revealing module pattern var createWorker = function() { // Private implementation details var workCount = 0; var task1 = function() { workCount += 1; console.log("task1 " + workCount); }; var task2 = function() { workCount += 1; console.log("task2 " + workCount); }; return { // Public API // Job1 points to task1 job1: task1, job2: task2 }; } // Global variable (bad) var worker = createWorker(); worker.job1(); worker.job2(); worker.job2(); worker.job2(); }());

A lot of JS libraries use IFFY’s to control the scope of variables, and avoid global variables!

| | # 
# Sunday, 22 December 2013

http://pluralsight.com/training/Courses/TableOfContents/play-by-play-wahlin-allen

“Web interface helps picks between 2 airline flight options for an upcoming business trip, usable on mobile device”

What data needs to be on the screen?

  • airline
  • times
  • cities
  • number of layovers..segments
  • duration
  • price
  • date

Data first..
Budget..simplify..budget..deadline..early prototype is good

summary vs detail
baby steps…Dan tends to over analyse..ie the ‘proper way’

Start

git console window.. git init airlines
sln is called Airlines..
default.html

NuGet

  • bootstrap
  • angularjs.core (John Papa) – prerelease

image
Blank solution.. then empty web project or something really simple..

webessentials .. zen coding

div.row then tab

App folder for angular stuff.

Emphasize what bits are important

WebAPI

image
So they’ve got this far starting at the UI, then doing interactions and business login on the UI.

image

then talking about async.. then talking about WebAPI.. /api/flight  brings back 42

image

Mock stuff up asap

Data first!

| | #