SlideShare a Scribd company logo
1 of 40
Download to read offline
JQUERY & 10,000
GLOBAL FUNCTIONS
Working with Legacy JavaScript
WHO IS THIS
GUY?
@guyroyse
guy@guyroyse.com
guyroyse.com
Presentation Business Logic Datastore
Presentation Business Logic Data Access
Our Concern The Mapping Their Concern
Presentation Business Logic Data Access
WHAT DOES THIS HAVE TO
DO WITH JAVASCRIPT?
STRATEGY VS DRIFT
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0;">
<title>GuyRoyse.com | Blog</title>
<link rel="icon" type="image/jpg" href="/images/alien-sunrise-icon.png">
<link rel="stylesheet" href=“/site.css">
<script>
💩</script>
</head>
<body>
…
</body>
</html>
SOLUTION #1: WE NEED A FRAMEWORK!
SOLUTION #2: WE NEED A REWRITE!
A new tiger team is selected. Everyone wants to be on this team because it’s a
green-field project. They get to start over and create something truly beautiful.
But only the best and brightest are chosen for the tiger team. Everyone else must
continue to maintain the current system.
Now the two teams are in a race. The tiger team must build a new system that
does everything that the old system does. Not only that, they have to keep up
with the changes that are continuously being made to the old system.
Management will not replace the old system until the new system can do
everything that the old system does.
This race can go on for a very long time. I’ve seen it take 10 years. And by the
time it’s done, the original members of the tiger team are long gone, and the
current members are demanding that the new system be redesigned because it’s
such a mess.
Martin, Robert C. (2008-08-01). Clean Code: A Handbook of Agile Software Craftsmanship (p. 5).
Pearson Education (USA). Kindle Edition.
THE REAL SOLUTION
Untestable
Code
Testable
Code
Tested
Code
TDD
Very Careful
Refactor
Characterization
Tests
Failing Test
WHAT’S A 27-LETTER WORD FOR “CORN”?
THE SIZZLE
I have code in the HTML or in an associated
JavaScript file that does some sort of fancy UI thing
in a dated way.
Problem
Solution Refactor to use modern CSS and test manually.
There is very little point in putting automated tests
around visual effects.
index.html
<script>
function addDropShadow(tag) {
tag.style.backgroundColor = "black";
}
function removeDropShadow(tag) {
tag.style.backgroundColor = "";
}
</script>
<a onmouseenter="addDropShadow(this)" onmouseleave=“removeDropShadow(this)"
href="somepage.jsp">Rollover Test</a>
index.html
<style>
.rollover:hover {
background-color: black;
}
</style>
<a class="rollover">Rollover Test</a>
CODE IN THE HTML
I have code in the HTML. It cannot be loaded into a
test harness to test it.
Problem
Solution Move code a .js file and add a script tag if needed.
Surround code in question with a test if possible or
extract a method and test that. If there is code in
event attributes in the HTML, used jQuery to bind
to those events instead.
index.html
<script>
function doAwesomeThing() {
thing.doAwesomeStuff("Awesome App is Awesome");
}
</script>
<a onclick="doAwesomeThing()">Awesome Thing</a>
index.html
<script src="awesome.js"></script>
<a id="awesomeThing">Awesome Thing</a>
awesome.js
$('#awesomeThing').on('click', onAwesomeThingClicked);
function onAwesomeThingClicked() {
thing.doAwesomeStuff("Awesome App is Awesome");
}
awesome-spec.js
describe("awesome thing", function() {
beforeEach(function() {
spyOn(thing, 'doAwesomeStuff');
});
it("does awesome stuff when clicked", function() {
onAwesomeThingClicked();
expect(thing.doAwesomeStuff).toHaveBeenCalledWith('Awesome App is Awesome');
});
});
DOM INTERACTION
A lot of the code interacts with the DOM and I
don’t have a DOM in my unit test.
Problem
Solution You can have a DOM in your unit tests. Mock out
HTML elements using Jasmine jQuery. Use jQuery
to trigger events and to validate that the DOM is
modified in the expected way.
index.html
<script src="awesome.js"></script>
<a id="awesomeThing">Awesome Thing</a>
<div id="toBeAwesome"/>
awesome.js
$('#awesomeThing').on('click', onAwesomeThingClicked);
function onAwesomeThingClicked() {
$('#toBeAwesome').html("Awesome App is Awesome");
}
awesome-spec.js
describe("awesome thing", function() {
beforeEach(function() {
setFixtures('<div id="toBeAwesome"/>');
});
it("does awesome stuff when clicked", function() {
onAwesomeThingClicked();
expect($('#toBeAwesome')).toHaveHtml('Awesome App is Awesome');
});
});
10,000 GLOBAL FUNCTIONS
I have functions everywhere, man!Problem
Solution Put a test around the global function. Move the
global function to a Module and replace the global
function with a variable that points to the Module.
Later, when no more code is accessing the global,
remove the global variable.
app.js
function transmogrify() {};
function transmute() {};
function transform() {};
app.js
var Mutators = {};
Mutators.transmogrify = function() {};
Mutators.transmute = function() {};
Mutators.transform = function() {};
var transmogrify = Mutators.transmogrify();
var transmute = Mutators.transmute();
var transform = Mutators.transform();
app-spec.js
describe("Mutators.transform", function() {
it("has mapping to legacy function", function() {
expect(transform).toBe(Mutators.transform);
});
it("does stuff", function() {
expect(Mutators.transform()).toBe(true);
});
});
NO UNITS
There are no units to test.Problem
Solution Carefully extract a function and place tests around
that function. Be careful not to create a 10,000
Global Functions problem.
app.js
$(function() {
var id = $('#id').val();
$.get('data/' + id, function(data) {
$('#name').val(data.name);
$('#rank').val(data.rank);
$('#serialNo').val(data.serial);
});
});
app.js
$(function() {
fetchAndUpdateDom();
});
function fetchAndUpdateDom() {
var id = $('#id').val();
$.get('data/' + id, function(data) {
updateDom(data);
});
};
function updateDom(data) {
$('#name').val(data.name);
$('#rank').val(data.rank);
$('#serialNo').val(data.serial);
}
JQUERY EVERYWHERE
I have jQuery calls inline everywhere in my code.Problem
Solution Using the Module pattern, migrate the jQuery that
interacts with the DOM into Passive Views. Migrate
the jQuery that makes AJAX calls into Adapters.
Place tests around these Modules.
app.js
function fetchAndUpdateDom() {
var id = $('#id').val();
$.get('data/' + id, function(data) {
$('#name').val(data.name);
$('#rank').val(data.rank);
$('#serialNo').val(data.serial);
});
};
app.js
var view = {
id : function() { return $('#id').val(); },
name : function(val) { $('#name').val(val); },
rank : function(val) { $('#rank').val(val); },
serialNo : function(val) { $('#serialNo').val(val); }
};
var data = {
fetch : function(id, callback) {
$.get('data/' + id, callback);
}
};
function fetchAndUpdateDom() {
data.fetch(view.id(), function(data) {
view.name(data.name); view.rank(data.rank); view.serialNo(data.serialNo);
});
}
REALLY UGLY FOR LOOPS
These nested for loops are hideous!Problem
Solution Use Underscore, lodash, or the built in array
functions like forEach, find, reduce, and map.
app.js
var values = [1,2,3,4,5], sum = 0, evens = [], doubles = [], i;
for(i = 0; i < values.length; i++) {
sum += values[i]
}
for(i = 0; i < values.length; i++) {
if (values[i] % 2 == 0) evens.push(values[i]);
}
for(i = 0; i < values.length; i++) {
doubles.push(values[i] *2);
}
app.js
var values = [1,2,3,4,5];
var sum = values.reduce(function(prev, value) {
return prev + value;
}, 0);
var evens = values.filter(function(value) {
return value % 2 === 0;
});
var doubles = values.map(function(value) {
return value * 2;
});
REALLY LONG FUNCTIONS
This function is too long!Problem
Solution Place a test around the function and refactor it to a
Revealing Module.
app.js
function doMaths(x, y) {
var add = x + y;
var sub = x - y;
var multi = x * y;
var div = x / y;
return { add: add, sub: sub, multi: multi, div: div };
};
app.js
var mather = (function() {
var _x, _y;
function doMaths(x, y) {
_x = x; _y = y;
return { add: add(), sub: sub(), multi: multi(), div: div() };
}
function add() { return _x + _y; }
function sub() { return _x - _y; }
function multi() { return _x * _y; }
function div() { return _x / _y; }
return { doMaths : doMaths };
})();
mather.doMaths(x, y);
ALMOST DUPLICATION
I have all these functions that do almost the same
thing but I can’t break them down.
Problem
Solution Use a Lambda Factory to create the functions for
you.
app.js
function getFirstNumberTimes(x) { return Number($('#first').val()) * x; }
function getSecondNumberTimes(x) { return Number($('#second').val()) * x; }
function getThirdNumberTimes(x) { return Number($('#third').val()) * x; }
app.js
function getFirstNumberTimes(x) { return getNumberTimes('#first', x); }
function getSecondNumberTimes(x) { return getNumberTimes('#second', x); }
function getThirdNumberTimes(x) { return getNumberTimes('#third', x); }
function getNumberTimes(id, x) {
return Number($(id).val()) * x;
}
app.js
function getTimesFn(id) {
return function(x) {
var val = $(id).val();
return Number(val) * x;
};
}
var getFirstNumberTimes = getTimesFn('#first');
var getSecondNumberTimes = getTimesFn('#second');
var getThirdNumberTimes = getTimesFn('#third');
SIDE-EFFECTS
When testing an object, I get side effects.Problem
Solution This is really just the problem of using globals.
JavaScript’s dynamic nature makes global objects
easy to implement. Avoid this and create Factory
Functions instead of global Modules.
app.js
var statefullThing = (function() {
var _name = "Alice";
function getName() { return _name; }
function setName(name) { _name = name; }
return { getName: getName, setName: setName };
})();
app-spec.js
describe("statefulThing", function() {
var subject = statefullThing;
it("has a settable name", function() {
subject.setName('Bob');
expect(subject.getName()).toBe('Bob');
});
it("has expected default name", function() {
expect(subject.getName()).toBe('Alice');
});
});
app.js
function statefuleThingFactory() {
var _name = "Alice";
function getName() { return _name; }
function setName(name) { _name = name; }
return { getName: getName, setName: setName };
};
var statefulThing = statefulThingFactory();
app-spec.js
describe("statefulThing", function() {
var subject;
beforeEach(function() {
subject = statefulThingFactory();
});
it("has a settable name", function() {
subject.setName('Bob');
expect(subject.getName()).toBe('Bob');
});
it("has expected default name", function() {
expect(subject.getName()).toBe('Alice');
});
});
PYRAMIDS OF DOOM
My AJAX calls are nested really deeply and I have
some timing issues with them.
Problem
Solution Use Promises to remove the nesting and force the
call order to what is needed.
app.js
$.get('orders.json', function(orders) {
var order = findOrder(orders);
updateDom(order);
$.get('items/' + order.id, function(items) {
var item = findItem(items);
updateDom(item);
$.get('details/' + item.id, function(details) {
udpateDom(details);
});
});
});
app.js
get('orders.json').then(function(orders) {
var order = findOrder(orders);
updateDom(order);
return get('items/' + order);
}).then(function(items) {
var item = findItem(items);
updateDom(item);
return get('details/' + item.id);
}).then(function(details) {
updateDom(details);
});
app.js
function get(url) {
var deferred = Q.defer();
$.get({
url : url,
success: function(data) {
return deferred.resolve(data);
},
error: function(xhr, status, error) {
return deferred.reject(error);
}
});
return deferred.promise();
}
get('orders.json').then(function(orders) {
var order = findOrder(orders);
updateDom(order);
return get('items/' + order);
}).then(function(items) {
var item = findItem(items);
updateDom(item);
return get('details/' + item.id);
}).then(function(details) {
updateDom(details);
});
NOT SURE IF I SHOULD ASK A
QUESTION
OR JUST RUN FOR THE DOOR
THANKS!
@guyroyse
guy@guyroyse.com
guyroyse.com

More Related Content

What's hot

AngularJS Animations
AngularJS AnimationsAngularJS Animations
AngularJS AnimationsEyal Vardi
 
Good karma: UX Patterns and Unit Testing in Angular with Karma
Good karma: UX Patterns and Unit Testing in Angular with KarmaGood karma: UX Patterns and Unit Testing in Angular with Karma
Good karma: UX Patterns and Unit Testing in Angular with KarmaExoLeaders.com
 
Javascript unit testing, yes we can e big
Javascript unit testing, yes we can   e bigJavascript unit testing, yes we can   e big
Javascript unit testing, yes we can e bigAndy Peterson
 
GDayX - Advanced Angular.JS
GDayX - Advanced Angular.JSGDayX - Advanced Angular.JS
GDayX - Advanced Angular.JSNicolas Embleton
 
Tweaking the interactive grid
Tweaking the interactive gridTweaking the interactive grid
Tweaking the interactive gridRoel Hartman
 
AngularJS with TypeScript and Windows Azure Mobile Services
AngularJS with TypeScript and Windows Azure Mobile ServicesAngularJS with TypeScript and Windows Azure Mobile Services
AngularJS with TypeScript and Windows Azure Mobile ServicesRainer Stropek
 
Crossing platforms with JavaScript & React
Crossing platforms with JavaScript & React Crossing platforms with JavaScript & React
Crossing platforms with JavaScript & React Robert DeLuca
 
Jquery Complete Presentation along with Javascript Basics
Jquery Complete Presentation along with Javascript BasicsJquery Complete Presentation along with Javascript Basics
Jquery Complete Presentation along with Javascript BasicsEPAM Systems
 
PHPUnit Episode iv.iii: Return of the tests
PHPUnit Episode iv.iii: Return of the testsPHPUnit Episode iv.iii: Return of the tests
PHPUnit Episode iv.iii: Return of the testsMichelangelo van Dam
 
Owl: The New Odoo UI Framework
Owl: The New Odoo UI FrameworkOwl: The New Odoo UI Framework
Owl: The New Odoo UI FrameworkOdoo
 
Ultimate Introduction To AngularJS
Ultimate Introduction To AngularJSUltimate Introduction To AngularJS
Ultimate Introduction To AngularJSJacopo Nardiello
 
Using Task Queues and D3.js to build an analytics product on App Engine
Using Task Queues and D3.js to build an analytics product on App EngineUsing Task Queues and D3.js to build an analytics product on App Engine
Using Task Queues and D3.js to build an analytics product on App EngineRiver of Talent
 
DOM Scripting Toolkit - jQuery
DOM Scripting Toolkit - jQueryDOM Scripting Toolkit - jQuery
DOM Scripting Toolkit - jQueryRemy Sharp
 
Be pragmatic, be SOLID (at Boiling Frogs, Wrocław)
Be pragmatic, be SOLID (at Boiling Frogs, Wrocław)Be pragmatic, be SOLID (at Boiling Frogs, Wrocław)
Be pragmatic, be SOLID (at Boiling Frogs, Wrocław)Krzysztof Menżyk
 

What's hot (20)

AngularJS Animations
AngularJS AnimationsAngularJS Animations
AngularJS Animations
 
Good karma: UX Patterns and Unit Testing in Angular with Karma
Good karma: UX Patterns and Unit Testing in Angular with KarmaGood karma: UX Patterns and Unit Testing in Angular with Karma
Good karma: UX Patterns and Unit Testing in Angular with Karma
 
jQuery in 15 minutes
jQuery in 15 minutesjQuery in 15 minutes
jQuery in 15 minutes
 
Javascript unit testing, yes we can e big
Javascript unit testing, yes we can   e bigJavascript unit testing, yes we can   e big
Javascript unit testing, yes we can e big
 
GDayX - Advanced Angular.JS
GDayX - Advanced Angular.JSGDayX - Advanced Angular.JS
GDayX - Advanced Angular.JS
 
Tweaking the interactive grid
Tweaking the interactive gridTweaking the interactive grid
Tweaking the interactive grid
 
Advanced Django
Advanced DjangoAdvanced Django
Advanced Django
 
Taming Command Bus
Taming Command BusTaming Command Bus
Taming Command Bus
 
AngularJS with TypeScript and Windows Azure Mobile Services
AngularJS with TypeScript and Windows Azure Mobile ServicesAngularJS with TypeScript and Windows Azure Mobile Services
AngularJS with TypeScript and Windows Azure Mobile Services
 
KISS Automation.py
KISS Automation.pyKISS Automation.py
KISS Automation.py
 
Crossing platforms with JavaScript & React
Crossing platforms with JavaScript & React Crossing platforms with JavaScript & React
Crossing platforms with JavaScript & React
 
Jquery Complete Presentation along with Javascript Basics
Jquery Complete Presentation along with Javascript BasicsJquery Complete Presentation along with Javascript Basics
Jquery Complete Presentation along with Javascript Basics
 
Angular mix chrisnoring
Angular mix chrisnoringAngular mix chrisnoring
Angular mix chrisnoring
 
PHPUnit Episode iv.iii: Return of the tests
PHPUnit Episode iv.iii: Return of the testsPHPUnit Episode iv.iii: Return of the tests
PHPUnit Episode iv.iii: Return of the tests
 
Hooks WCSD12
Hooks WCSD12Hooks WCSD12
Hooks WCSD12
 
Owl: The New Odoo UI Framework
Owl: The New Odoo UI FrameworkOwl: The New Odoo UI Framework
Owl: The New Odoo UI Framework
 
Ultimate Introduction To AngularJS
Ultimate Introduction To AngularJSUltimate Introduction To AngularJS
Ultimate Introduction To AngularJS
 
Using Task Queues and D3.js to build an analytics product on App Engine
Using Task Queues and D3.js to build an analytics product on App EngineUsing Task Queues and D3.js to build an analytics product on App Engine
Using Task Queues and D3.js to build an analytics product on App Engine
 
DOM Scripting Toolkit - jQuery
DOM Scripting Toolkit - jQueryDOM Scripting Toolkit - jQuery
DOM Scripting Toolkit - jQuery
 
Be pragmatic, be SOLID (at Boiling Frogs, Wrocław)
Be pragmatic, be SOLID (at Boiling Frogs, Wrocław)Be pragmatic, be SOLID (at Boiling Frogs, Wrocław)
Be pragmatic, be SOLID (at Boiling Frogs, Wrocław)
 

Viewers also liked

jQueryのその先へ〜Webフロントエンドの全体感をつかもう〜
jQueryのその先へ〜Webフロントエンドの全体感をつかもう〜jQueryのその先へ〜Webフロントエンドの全体感をつかもう〜
jQueryのその先へ〜Webフロントエンドの全体感をつかもう〜Kazuyoshi Tsuchiya
 
jQuery Learning
jQuery LearningjQuery Learning
jQuery LearningUzair Ali
 
A Power User's Intro to jQuery Awesomeness in SharePoint
A Power User's Intro to jQuery Awesomeness in SharePointA Power User's Intro to jQuery Awesomeness in SharePoint
A Power User's Intro to jQuery Awesomeness in SharePointMark Rackley
 

Viewers also liked (7)

Programação Web com jQuery
Programação Web com jQueryProgramação Web com jQuery
Programação Web com jQuery
 
Jquery introduction
Jquery introductionJquery introduction
Jquery introduction
 
jQueryのその先へ〜Webフロントエンドの全体感をつかもう〜
jQueryのその先へ〜Webフロントエンドの全体感をつかもう〜jQueryのその先へ〜Webフロントエンドの全体感をつかもう〜
jQueryのその先へ〜Webフロントエンドの全体感をつかもう〜
 
jQuery Learning
jQuery LearningjQuery Learning
jQuery Learning
 
A Power User's Intro to jQuery Awesomeness in SharePoint
A Power User's Intro to jQuery Awesomeness in SharePointA Power User's Intro to jQuery Awesomeness in SharePoint
A Power User's Intro to jQuery Awesomeness in SharePoint
 
The jQuery Divide
The jQuery DivideThe jQuery Divide
The jQuery Divide
 
jQuery Introduction
jQuery IntroductionjQuery Introduction
jQuery Introduction
 

Similar to jQuery & 10,000 Global Functions: Working with Legacy JavaScript

Javascript first-class citizenery
Javascript first-class citizeneryJavascript first-class citizenery
Javascript first-class citizenerytoddbr
 
Dependency Management with RequireJS
Dependency Management with RequireJSDependency Management with RequireJS
Dependency Management with RequireJSAaronius
 
Avinash Kundaliya: Javascript and WordPress
Avinash Kundaliya: Javascript and WordPressAvinash Kundaliya: Javascript and WordPress
Avinash Kundaliya: Javascript and WordPresswpnepal
 
Building Large jQuery Applications
Building Large jQuery ApplicationsBuilding Large jQuery Applications
Building Large jQuery ApplicationsRebecca Murphey
 
Backbone js in drupal core
Backbone js in drupal coreBackbone js in drupal core
Backbone js in drupal coreMarcin Wosinek
 
JQuery In Drupal
JQuery In DrupalJQuery In Drupal
JQuery In Drupalkatbailey
 
Single Page Web Applications with CoffeeScript, Backbone and Jasmine
Single Page Web Applications with CoffeeScript, Backbone and JasmineSingle Page Web Applications with CoffeeScript, Backbone and Jasmine
Single Page Web Applications with CoffeeScript, Backbone and JasminePaulo Ragonha
 
jQuery - 10 Time-Savers You (Maybe) Don't Know
jQuery - 10 Time-Savers You (Maybe) Don't KnowjQuery - 10 Time-Savers You (Maybe) Don't Know
jQuery - 10 Time-Savers You (Maybe) Don't Knowgirish82
 
HTML5 for the Silverlight Guy
HTML5 for the Silverlight GuyHTML5 for the Silverlight Guy
HTML5 for the Silverlight GuyDavid Padbury
 
JavaScript Growing Up
JavaScript Growing UpJavaScript Growing Up
JavaScript Growing UpDavid Padbury
 
Future of Web Apps: Google Gears
Future of Web Apps: Google GearsFuture of Web Apps: Google Gears
Future of Web Apps: Google Gearsdion
 
Drupal & javascript
Drupal & javascriptDrupal & javascript
Drupal & javascriptAlmog Baku
 
Javascript Memory leaks and Performance & Angular
Javascript Memory leaks and Performance & AngularJavascript Memory leaks and Performance & Angular
Javascript Memory leaks and Performance & AngularErik Guzman
 
09 - express nodes on the right angle - vitaliy basyuk - it event 2013 (5)
09 - express nodes on the right angle - vitaliy basyuk - it event 2013 (5)09 - express nodes on the right angle - vitaliy basyuk - it event 2013 (5)
09 - express nodes on the right angle - vitaliy basyuk - it event 2013 (5)Igor Bronovskyy
 
Taming that client side mess with Backbone.js
Taming that client side mess with Backbone.jsTaming that client side mess with Backbone.js
Taming that client side mess with Backbone.jsJarod Ferguson
 
Secrets of JavaScript Libraries
Secrets of JavaScript LibrariesSecrets of JavaScript Libraries
Secrets of JavaScript Librariesjeresig
 
[Coscup 2012] JavascriptMVC
[Coscup 2012] JavascriptMVC[Coscup 2012] JavascriptMVC
[Coscup 2012] JavascriptMVCAlive Kuo
 

Similar to jQuery & 10,000 Global Functions: Working with Legacy JavaScript (20)

Javascript first-class citizenery
Javascript first-class citizeneryJavascript first-class citizenery
Javascript first-class citizenery
 
Dependency Management with RequireJS
Dependency Management with RequireJSDependency Management with RequireJS
Dependency Management with RequireJS
 
Avinash Kundaliya: Javascript and WordPress
Avinash Kundaliya: Javascript and WordPressAvinash Kundaliya: Javascript and WordPress
Avinash Kundaliya: Javascript and WordPress
 
Clean Javascript
Clean JavascriptClean Javascript
Clean Javascript
 
Building Large jQuery Applications
Building Large jQuery ApplicationsBuilding Large jQuery Applications
Building Large jQuery Applications
 
Backbone js in drupal core
Backbone js in drupal coreBackbone js in drupal core
Backbone js in drupal core
 
JQuery In Drupal
JQuery In DrupalJQuery In Drupal
JQuery In Drupal
 
React lecture
React lectureReact lecture
React lecture
 
Single Page Web Applications with CoffeeScript, Backbone and Jasmine
Single Page Web Applications with CoffeeScript, Backbone and JasmineSingle Page Web Applications with CoffeeScript, Backbone and Jasmine
Single Page Web Applications with CoffeeScript, Backbone and Jasmine
 
jQuery - 10 Time-Savers You (Maybe) Don't Know
jQuery - 10 Time-Savers You (Maybe) Don't KnowjQuery - 10 Time-Savers You (Maybe) Don't Know
jQuery - 10 Time-Savers You (Maybe) Don't Know
 
HTML5 for the Silverlight Guy
HTML5 for the Silverlight GuyHTML5 for the Silverlight Guy
HTML5 for the Silverlight Guy
 
JavaScript Growing Up
JavaScript Growing UpJavaScript Growing Up
JavaScript Growing Up
 
Introduction to jQuery
Introduction to jQueryIntroduction to jQuery
Introduction to jQuery
 
Future of Web Apps: Google Gears
Future of Web Apps: Google GearsFuture of Web Apps: Google Gears
Future of Web Apps: Google Gears
 
Drupal & javascript
Drupal & javascriptDrupal & javascript
Drupal & javascript
 
Javascript Memory leaks and Performance & Angular
Javascript Memory leaks and Performance & AngularJavascript Memory leaks and Performance & Angular
Javascript Memory leaks and Performance & Angular
 
09 - express nodes on the right angle - vitaliy basyuk - it event 2013 (5)
09 - express nodes on the right angle - vitaliy basyuk - it event 2013 (5)09 - express nodes on the right angle - vitaliy basyuk - it event 2013 (5)
09 - express nodes on the right angle - vitaliy basyuk - it event 2013 (5)
 
Taming that client side mess with Backbone.js
Taming that client side mess with Backbone.jsTaming that client side mess with Backbone.js
Taming that client side mess with Backbone.js
 
Secrets of JavaScript Libraries
Secrets of JavaScript LibrariesSecrets of JavaScript Libraries
Secrets of JavaScript Libraries
 
[Coscup 2012] JavascriptMVC
[Coscup 2012] JavascriptMVC[Coscup 2012] JavascriptMVC
[Coscup 2012] JavascriptMVC
 

More from Guy Royse

Putting the D&D in TDD
Putting the D&D in TDDPutting the D&D in TDD
Putting the D&D in TDDGuy Royse
 
Machine Learning for Fun - Finding Bigfoot with the Nexosis API
Machine Learning for Fun - Finding Bigfoot with the Nexosis APIMachine Learning for Fun - Finding Bigfoot with the Nexosis API
Machine Learning for Fun - Finding Bigfoot with the Nexosis APIGuy Royse
 
Machine Learning for Gamers - Dungeon Forecasts & Dragon Regressions
Machine Learning for Gamers - Dungeon Forecasts & Dragon RegressionsMachine Learning for Gamers - Dungeon Forecasts & Dragon Regressions
Machine Learning for Gamers - Dungeon Forecasts & Dragon RegressionsGuy Royse
 
The Code Christmas Tree: Selling the Investment for Technical Debt
The Code Christmas Tree: Selling the Investment for Technical DebtThe Code Christmas Tree: Selling the Investment for Technical Debt
The Code Christmas Tree: Selling the Investment for Technical DebtGuy Royse
 
Mad Computer Science: Testing COBOL with RSpec
Mad Computer Science: Testing COBOL with RSpecMad Computer Science: Testing COBOL with RSpec
Mad Computer Science: Testing COBOL with RSpecGuy Royse
 
Programming on Bare Metal: Controlling Circuits with Code
Programming on Bare Metal: Controlling Circuits with CodeProgramming on Bare Metal: Controlling Circuits with Code
Programming on Bare Metal: Controlling Circuits with CodeGuy Royse
 
Putting the D&D in TDD
Putting the D&D in TDDPutting the D&D in TDD
Putting the D&D in TDDGuy Royse
 
Those Who Know History are Doomed to Watch Others Repeat It
Those Who Know History are Doomed to Watch Others Repeat ItThose Who Know History are Doomed to Watch Others Repeat It
Those Who Know History are Doomed to Watch Others Repeat ItGuy Royse
 
Understanding Prototypal Inheritance
Understanding Prototypal InheritanceUnderstanding Prototypal Inheritance
Understanding Prototypal InheritanceGuy Royse
 

More from Guy Royse (9)

Putting the D&D in TDD
Putting the D&D in TDDPutting the D&D in TDD
Putting the D&D in TDD
 
Machine Learning for Fun - Finding Bigfoot with the Nexosis API
Machine Learning for Fun - Finding Bigfoot with the Nexosis APIMachine Learning for Fun - Finding Bigfoot with the Nexosis API
Machine Learning for Fun - Finding Bigfoot with the Nexosis API
 
Machine Learning for Gamers - Dungeon Forecasts & Dragon Regressions
Machine Learning for Gamers - Dungeon Forecasts & Dragon RegressionsMachine Learning for Gamers - Dungeon Forecasts & Dragon Regressions
Machine Learning for Gamers - Dungeon Forecasts & Dragon Regressions
 
The Code Christmas Tree: Selling the Investment for Technical Debt
The Code Christmas Tree: Selling the Investment for Technical DebtThe Code Christmas Tree: Selling the Investment for Technical Debt
The Code Christmas Tree: Selling the Investment for Technical Debt
 
Mad Computer Science: Testing COBOL with RSpec
Mad Computer Science: Testing COBOL with RSpecMad Computer Science: Testing COBOL with RSpec
Mad Computer Science: Testing COBOL with RSpec
 
Programming on Bare Metal: Controlling Circuits with Code
Programming on Bare Metal: Controlling Circuits with CodeProgramming on Bare Metal: Controlling Circuits with Code
Programming on Bare Metal: Controlling Circuits with Code
 
Putting the D&D in TDD
Putting the D&D in TDDPutting the D&D in TDD
Putting the D&D in TDD
 
Those Who Know History are Doomed to Watch Others Repeat It
Those Who Know History are Doomed to Watch Others Repeat ItThose Who Know History are Doomed to Watch Others Repeat It
Those Who Know History are Doomed to Watch Others Repeat It
 
Understanding Prototypal Inheritance
Understanding Prototypal InheritanceUnderstanding Prototypal Inheritance
Understanding Prototypal Inheritance
 

Recently uploaded

DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDropbox
 
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...Zilliz
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingEdi Saputra
 
Corporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxCorporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxRustici Software
 
ICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesrafiqahmad00786416
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfsudhanshuwaghmare1
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)wesley chun
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
Apidays Singapore 2024 - Modernizing Securities Finance by Madhu Subbu
Apidays Singapore 2024 - Modernizing Securities Finance by Madhu SubbuApidays Singapore 2024 - Modernizing Securities Finance by Madhu Subbu
Apidays Singapore 2024 - Modernizing Securities Finance by Madhu Subbuapidays
 
Navi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Navi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot ModelNavi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Navi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot ModelDeepika Singh
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...apidays
 
AXA XL - Insurer Innovation Award Americas 2024
AXA XL - Insurer Innovation Award Americas 2024AXA XL - Insurer Innovation Award Americas 2024
AXA XL - Insurer Innovation Award Americas 2024The Digital Insurer
 
Ransomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdfRansomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdfOverkill Security
 
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWEREMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWERMadyBayot
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Drew Madelung
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc
 
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...apidays
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodJuan lago vázquez
 
MS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectorsMS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectorsNanddeep Nachan
 

Recently uploaded (20)

DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor Presentation
 
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
 
Corporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxCorporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptx
 
ICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesICT role in 21st century education and its challenges
ICT role in 21st century education and its challenges
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Apidays Singapore 2024 - Modernizing Securities Finance by Madhu Subbu
Apidays Singapore 2024 - Modernizing Securities Finance by Madhu SubbuApidays Singapore 2024 - Modernizing Securities Finance by Madhu Subbu
Apidays Singapore 2024 - Modernizing Securities Finance by Madhu Subbu
 
Navi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Navi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot ModelNavi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Navi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot Model
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...
 
AXA XL - Insurer Innovation Award Americas 2024
AXA XL - Insurer Innovation Award Americas 2024AXA XL - Insurer Innovation Award Americas 2024
AXA XL - Insurer Innovation Award Americas 2024
 
Ransomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdfRansomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdf
 
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWEREMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
 
MS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectorsMS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectors
 

jQuery & 10,000 Global Functions: Working with Legacy JavaScript

  • 1. JQUERY & 10,000 GLOBAL FUNCTIONS Working with Legacy JavaScript
  • 3.
  • 6. Our Concern The Mapping Their Concern
  • 8. WHAT DOES THIS HAVE TO DO WITH JAVASCRIPT?
  • 10. <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0;"> <title>GuyRoyse.com | Blog</title> <link rel="icon" type="image/jpg" href="/images/alien-sunrise-icon.png"> <link rel="stylesheet" href=“/site.css"> <script> 💩</script> </head> <body> … </body> </html>
  • 11. SOLUTION #1: WE NEED A FRAMEWORK!
  • 12. SOLUTION #2: WE NEED A REWRITE! A new tiger team is selected. Everyone wants to be on this team because it’s a green-field project. They get to start over and create something truly beautiful. But only the best and brightest are chosen for the tiger team. Everyone else must continue to maintain the current system. Now the two teams are in a race. The tiger team must build a new system that does everything that the old system does. Not only that, they have to keep up with the changes that are continuously being made to the old system. Management will not replace the old system until the new system can do everything that the old system does. This race can go on for a very long time. I’ve seen it take 10 years. And by the time it’s done, the original members of the tiger team are long gone, and the current members are demanding that the new system be redesigned because it’s such a mess. Martin, Robert C. (2008-08-01). Clean Code: A Handbook of Agile Software Craftsmanship (p. 5). Pearson Education (USA). Kindle Edition.
  • 15. WHAT’S A 27-LETTER WORD FOR “CORN”?
  • 16. THE SIZZLE I have code in the HTML or in an associated JavaScript file that does some sort of fancy UI thing in a dated way. Problem Solution Refactor to use modern CSS and test manually. There is very little point in putting automated tests around visual effects.
  • 17. index.html <script> function addDropShadow(tag) { tag.style.backgroundColor = "black"; } function removeDropShadow(tag) { tag.style.backgroundColor = ""; } </script> <a onmouseenter="addDropShadow(this)" onmouseleave=“removeDropShadow(this)" href="somepage.jsp">Rollover Test</a> index.html <style> .rollover:hover { background-color: black; } </style> <a class="rollover">Rollover Test</a>
  • 18. CODE IN THE HTML I have code in the HTML. It cannot be loaded into a test harness to test it. Problem Solution Move code a .js file and add a script tag if needed. Surround code in question with a test if possible or extract a method and test that. If there is code in event attributes in the HTML, used jQuery to bind to those events instead.
  • 19. index.html <script> function doAwesomeThing() { thing.doAwesomeStuff("Awesome App is Awesome"); } </script> <a onclick="doAwesomeThing()">Awesome Thing</a> index.html <script src="awesome.js"></script> <a id="awesomeThing">Awesome Thing</a> awesome.js $('#awesomeThing').on('click', onAwesomeThingClicked); function onAwesomeThingClicked() { thing.doAwesomeStuff("Awesome App is Awesome"); } awesome-spec.js describe("awesome thing", function() { beforeEach(function() { spyOn(thing, 'doAwesomeStuff'); }); it("does awesome stuff when clicked", function() { onAwesomeThingClicked(); expect(thing.doAwesomeStuff).toHaveBeenCalledWith('Awesome App is Awesome'); }); });
  • 20. DOM INTERACTION A lot of the code interacts with the DOM and I don’t have a DOM in my unit test. Problem Solution You can have a DOM in your unit tests. Mock out HTML elements using Jasmine jQuery. Use jQuery to trigger events and to validate that the DOM is modified in the expected way.
  • 21. index.html <script src="awesome.js"></script> <a id="awesomeThing">Awesome Thing</a> <div id="toBeAwesome"/> awesome.js $('#awesomeThing').on('click', onAwesomeThingClicked); function onAwesomeThingClicked() { $('#toBeAwesome').html("Awesome App is Awesome"); } awesome-spec.js describe("awesome thing", function() { beforeEach(function() { setFixtures('<div id="toBeAwesome"/>'); }); it("does awesome stuff when clicked", function() { onAwesomeThingClicked(); expect($('#toBeAwesome')).toHaveHtml('Awesome App is Awesome'); }); });
  • 22. 10,000 GLOBAL FUNCTIONS I have functions everywhere, man!Problem Solution Put a test around the global function. Move the global function to a Module and replace the global function with a variable that points to the Module. Later, when no more code is accessing the global, remove the global variable.
  • 23. app.js function transmogrify() {}; function transmute() {}; function transform() {}; app.js var Mutators = {}; Mutators.transmogrify = function() {}; Mutators.transmute = function() {}; Mutators.transform = function() {}; var transmogrify = Mutators.transmogrify(); var transmute = Mutators.transmute(); var transform = Mutators.transform(); app-spec.js describe("Mutators.transform", function() { it("has mapping to legacy function", function() { expect(transform).toBe(Mutators.transform); }); it("does stuff", function() { expect(Mutators.transform()).toBe(true); }); });
  • 24. NO UNITS There are no units to test.Problem Solution Carefully extract a function and place tests around that function. Be careful not to create a 10,000 Global Functions problem.
  • 25. app.js $(function() { var id = $('#id').val(); $.get('data/' + id, function(data) { $('#name').val(data.name); $('#rank').val(data.rank); $('#serialNo').val(data.serial); }); }); app.js $(function() { fetchAndUpdateDom(); }); function fetchAndUpdateDom() { var id = $('#id').val(); $.get('data/' + id, function(data) { updateDom(data); }); }; function updateDom(data) { $('#name').val(data.name); $('#rank').val(data.rank); $('#serialNo').val(data.serial); }
  • 26. JQUERY EVERYWHERE I have jQuery calls inline everywhere in my code.Problem Solution Using the Module pattern, migrate the jQuery that interacts with the DOM into Passive Views. Migrate the jQuery that makes AJAX calls into Adapters. Place tests around these Modules.
  • 27. app.js function fetchAndUpdateDom() { var id = $('#id').val(); $.get('data/' + id, function(data) { $('#name').val(data.name); $('#rank').val(data.rank); $('#serialNo').val(data.serial); }); }; app.js var view = { id : function() { return $('#id').val(); }, name : function(val) { $('#name').val(val); }, rank : function(val) { $('#rank').val(val); }, serialNo : function(val) { $('#serialNo').val(val); } }; var data = { fetch : function(id, callback) { $.get('data/' + id, callback); } }; function fetchAndUpdateDom() { data.fetch(view.id(), function(data) { view.name(data.name); view.rank(data.rank); view.serialNo(data.serialNo); }); }
  • 28. REALLY UGLY FOR LOOPS These nested for loops are hideous!Problem Solution Use Underscore, lodash, or the built in array functions like forEach, find, reduce, and map.
  • 29. app.js var values = [1,2,3,4,5], sum = 0, evens = [], doubles = [], i; for(i = 0; i < values.length; i++) { sum += values[i] } for(i = 0; i < values.length; i++) { if (values[i] % 2 == 0) evens.push(values[i]); } for(i = 0; i < values.length; i++) { doubles.push(values[i] *2); } app.js var values = [1,2,3,4,5]; var sum = values.reduce(function(prev, value) { return prev + value; }, 0); var evens = values.filter(function(value) { return value % 2 === 0; }); var doubles = values.map(function(value) { return value * 2; });
  • 30. REALLY LONG FUNCTIONS This function is too long!Problem Solution Place a test around the function and refactor it to a Revealing Module.
  • 31. app.js function doMaths(x, y) { var add = x + y; var sub = x - y; var multi = x * y; var div = x / y; return { add: add, sub: sub, multi: multi, div: div }; }; app.js var mather = (function() { var _x, _y; function doMaths(x, y) { _x = x; _y = y; return { add: add(), sub: sub(), multi: multi(), div: div() }; } function add() { return _x + _y; } function sub() { return _x - _y; } function multi() { return _x * _y; } function div() { return _x / _y; } return { doMaths : doMaths }; })(); mather.doMaths(x, y);
  • 32. ALMOST DUPLICATION I have all these functions that do almost the same thing but I can’t break them down. Problem Solution Use a Lambda Factory to create the functions for you.
  • 33. app.js function getFirstNumberTimes(x) { return Number($('#first').val()) * x; } function getSecondNumberTimes(x) { return Number($('#second').val()) * x; } function getThirdNumberTimes(x) { return Number($('#third').val()) * x; } app.js function getFirstNumberTimes(x) { return getNumberTimes('#first', x); } function getSecondNumberTimes(x) { return getNumberTimes('#second', x); } function getThirdNumberTimes(x) { return getNumberTimes('#third', x); } function getNumberTimes(id, x) { return Number($(id).val()) * x; } app.js function getTimesFn(id) { return function(x) { var val = $(id).val(); return Number(val) * x; }; } var getFirstNumberTimes = getTimesFn('#first'); var getSecondNumberTimes = getTimesFn('#second'); var getThirdNumberTimes = getTimesFn('#third');
  • 34. SIDE-EFFECTS When testing an object, I get side effects.Problem Solution This is really just the problem of using globals. JavaScript’s dynamic nature makes global objects easy to implement. Avoid this and create Factory Functions instead of global Modules.
  • 35. app.js var statefullThing = (function() { var _name = "Alice"; function getName() { return _name; } function setName(name) { _name = name; } return { getName: getName, setName: setName }; })(); app-spec.js describe("statefulThing", function() { var subject = statefullThing; it("has a settable name", function() { subject.setName('Bob'); expect(subject.getName()).toBe('Bob'); }); it("has expected default name", function() { expect(subject.getName()).toBe('Alice'); }); }); app.js function statefuleThingFactory() { var _name = "Alice"; function getName() { return _name; } function setName(name) { _name = name; } return { getName: getName, setName: setName }; }; var statefulThing = statefulThingFactory(); app-spec.js describe("statefulThing", function() { var subject; beforeEach(function() { subject = statefulThingFactory(); }); it("has a settable name", function() { subject.setName('Bob'); expect(subject.getName()).toBe('Bob'); }); it("has expected default name", function() { expect(subject.getName()).toBe('Alice'); }); });
  • 36. PYRAMIDS OF DOOM My AJAX calls are nested really deeply and I have some timing issues with them. Problem Solution Use Promises to remove the nesting and force the call order to what is needed.
  • 37. app.js $.get('orders.json', function(orders) { var order = findOrder(orders); updateDom(order); $.get('items/' + order.id, function(items) { var item = findItem(items); updateDom(item); $.get('details/' + item.id, function(details) { udpateDom(details); }); }); }); app.js get('orders.json').then(function(orders) { var order = findOrder(orders); updateDom(order); return get('items/' + order); }).then(function(items) { var item = findItem(items); updateDom(item); return get('details/' + item.id); }).then(function(details) { updateDom(details); });
  • 38. app.js function get(url) { var deferred = Q.defer(); $.get({ url : url, success: function(data) { return deferred.resolve(data); }, error: function(xhr, status, error) { return deferred.reject(error); } }); return deferred.promise(); } get('orders.json').then(function(orders) { var order = findOrder(orders); updateDom(order); return get('items/' + order); }).then(function(items) { var item = findItem(items); updateDom(item); return get('details/' + item.id); }).then(function(details) { updateDom(details); });
  • 39. NOT SURE IF I SHOULD ASK A QUESTION OR JUST RUN FOR THE DOOR