Showing posts with label JavaScript. Show all posts
Showing posts with label JavaScript. Show all posts

Wednesday, August 14, 2013

Indiana Jones and the Temple of DOM Slides

I recently gave a talk at ThatConference 2013 titled "Indiana Jones and the Temple of DOM" in which I received a lot of requests to share the slides from attendees so I figured I'd share them with everyone.  I'll likely turn this into a video that I'll post online but until I get to that please enjoy the slides here:


I'd also love to hear your feedback and suggestions how I could make it better!

Friday, May 24, 2013

JavaScript Inheritance - HowTo Shoot Yourself In the Foot With Prototypes!


One thing that has long eluded me is a good understanding how JavaScript inheritance works when the parent constructor function has instance properties. The following code has a Widget parent class that has a messages properties. In this case we want each instance to be initialized with an empty messages array:



Before we set SubWidget's prototype to a new instance of our Prototype constructor on line 12 we get an object graph that looks like this:

After the code on line 12 is run the new keyword does its magic and ties everything together creating a new inheritance tree and a new scope.  Our object graph now looks something like this:

Do you see what the problem is yet? Lets create some instances of our subclass to highlight the issue:


Now our object graph looks like this:



Before I talk about the real problem here I'd like to step back and talk about the "type" property on the widget's constructor.  If it is not initialized by assignment each instance's "type" property actually points to the constructor's "type" property.  However, once it is initialized by assigning a value to like so: sub1.type = 'Fuzzy Bunny' it becomes a property of the instance, as shown in the new object graph:

Our bug should start to become clear now.  Let's look at the value of both sub1 and sub2's messages array:

JS Bin

Each object is sharing the same messages array! It would be tempting to fix this by adding another property to the SubWidget constructor like so:



However, what if we wanted to create other objects that extended Widget?  That new object would also need a messages array and pretty soon we have code that is a nightmare to maintain and extend.  Additionally, what if we wanted to add other properties to the Widget constcutor that were initialized when instances of its sub classes were constructed?  This isn't very reusable or flexible solution. 

In order to properly fix this all that needs to be done is  to add a single line of code to our SubWidget constructor that will invoke the Widget constructor with the same scope of our SubWidget constructor:



Now when we create new objects each instance has a new instance of the messages array:

JS Bin

Now our object graph is correct:





Monday, May 6, 2013

I'll Be Speaking About The DOM At ThatConferenece In August

I'm really excited to have been chosen as a speaker for this year's ThatConference conference in the Wisconsin Dells in August.  If you haven't heard of ThatConference before its billed as "Summer Camp For Geeks" and prides itself on being  a relaxed, fun, and wide-ranging conference.  It's also one of the few conferences where there are specific family friendly activities planned during the conference (being held at an indoor water park doesn't hurt in this regard).

With tracks on mobile, web, cloud, and "other" there each time slot is packed with interesting sessions from some top notch speakers.  I'm extremely honored to be amongst such amazing company.  One session I'd like to draw attention to is Mike Rohde's "Sketchnote Workshop".  I have the pleasure to work with Mike and have been through his workshop.  Even if you are a terrible drawer (like myself) you'll take away a lot of excellent information from this session.

My session is titled "Indiana Jones and the Temple of DOM" and will focus on using the browser's native Document API's to select and manipulate a page's contents without the help of a library like jQuery.  Why is this important?  Here I defer to Remy Sharp's "I know jQuery. Now What?"  TLDR, while jQuery super awesome every project doesn't need to start with immediately adding jQuery for it.  There are many cases where all of the events your project needs are already built right into the web Browser.

Friday, April 19, 2013

Kick Ass Cross-Platform Workflow With Grunt

My apologies for the vulgar title, but Grunt has me pretty excited these Days.  I work on a Mac at home and on a Windows machine at work, this means that cross platform tools are extremely important to my workflow. I hate having to use CodeKit at home and Scout at work to compile my .scss files.  Additionally tying a project to a platform specific tool means that its that much harder for others to get involved. Lately I've become a bit of a GruntJS fanboy, not only does it
meet my cross platform needs, but it cuts down the number of tools I need to use because it does so many things.
The watch plugin has made my workflow even better by allowing me to run Grunt tasks when files in my project are added, changed, or deleted. With watch whenever a .less or .scss file gets updated Grunt will see the change and automatically compile the file for me.  This post will walk you through installing watch and a compiler plugin and addresses a few of the gotcha's I ran into along the way. 

Install Grunt

Duh. Installing Grunt is out of the scope of this post but  the Grunt Homepage does an excellent job of walking you through the intstall (here's a hint you'll need to install Node too).  It's important to note here that version 0.4.0 and newer of Grunt works much differently than prior versions, and that the examples in this post will only work with version 0.4.0 or newer of Grunt.

Install Compiler Plugin

Once you have Grunt installed the next step is to get a compiler installed (since my current project is using Twitter Bootstrap I'm going to walk through setting up the LESS compiler in this post, however the process is the same for any other compiler).
To find the plugin you need the Grunt plugin page has a list of plugin's available for Grunt.  Clicking on a plugin will send you to the plugin's NPM page where you'll find documentation on the plugin and the command needed to install the plugin.

A quick not on plugins.  There are two type's of plugins "contrib" and "non-contrib".  The "contrib" plugins are official plugins and are maintained by the Grunt team.  I always prefer to use the "contrib" plugins whenever I can since they are generally better maintained and supported.
To install the Grunt LESS plugin:
  • open the terminal and navigate to the project's root directory in a terminal
  • type in npm install grunt-contrib-less --save-dev in the command line
  • hit enter
It really is that simple. The --save-dev command will ensure that the plugin, and its version, are added to your package.json file.
If you are not using a package.json file I strongly suggest you start. Using a package.json file means that you don't have to add your node_modules code to your distributions, users simply have to type in npm install in a terminal to install the dependencies.

Install The Watch Plugin

The next step is simple, install the watch plugin.  While still in your project's root directory in the terminal type in:
npm install grunt-contrib-watch --save-dev

Configure your Gruntfile

Before you go any further read the "Configuring Tasks" section of the Grunt website. This will save you a lot of time in the long run, I promise. Many plugins will assume that you know how to configure tasks and will leave these details out of their documentation.
A few points of frustration that I've run into that are covered in "Configuring Tasks" are:
  • Specifying the task name to configure. Typically the task name is the same as your plugin name.
  • Specifying source and destination files.  This is almost always left out of documentation and is almost always extremely important since a lot of plugins deal with manipulating files. 
  • Targets and how to use them (some plugins require targets and some do not, the bad news is that it's usually poorly documented whether a plugin uses them or not).
Configure the Compiler
Now that I've gotten that out of the way, lets walk through setting up the LESS compiler in the Gruntfile. In order to add a LESS task to the Gruntfile add a property named less to the object that is passed into the grunt.initConfig() function.  Since the LESS plugin requires targets (it will fail without them) I am going to specify a development target in the configuration.
A quick note on targets: if no target is specified when register or running a task ALL targets for a task will be executed.
The development target in this example only uses properties: src and dest. These properties are used to tell the LESS task where to find the .less files and where to put the compiled .css file. The syntax /**.*.less tells Grunt to get all files with a .less extension in the less directory and all of its sub-directories.

grunt.initConfig({

    less: {

        development : {

            src : [ 'less/**/*.less' ],

            dest : 'css/compiled-better.css'

        }

    }

)};

Configure Watch
The watch plugin does exactly what it's name implies, watches a directory for changes.  Since this plugin does not require the use of targets I'll skip them in this example and will put properties directly under the watch task. At a minimum watch needs two properties: files and tasks. The files property tells watch what files to look for changes for, and tasks property tells watch what tasks to run when a change is detected.
The example below is telling watch to listen for any changes to files with a.less extension in the less folder and any of its sub-folders and to run the less task when a change is detected.
watch: {

    files : [ 'less/**/*.less' ],

    tasks : [ 'less' ]

}
Register Tasks
The last step in configuring your Gruntfile is to register the less and watch tasks. To do this the following lines are added to the Gruntfile immediately after the grunt.initConfig() call:


grunt.initConfig({
    ...
});

grunt.loadNpmTasks('grunt-contrib-less');

grunt.loadNpmTasks('grunt-contrib-watch');

Run the Watch Task

The last step is to run the watch task. In a terminal window once again navigate to the root directory of the project and enter:
grunt watch
Grunt will run the watch task which will then tell you that its "Waiting...".  When a change is detected Grunt will spring into action and you'll see the normal Grunt messages start to appear in the console. When the tasks are complete watch will go back to the Waiting... status.



Monday, April 15, 2013

A Quick Look at e.target and e.currentTarget. And Bubbling.

Since jQuery makes such easy work of event listeners it's sometimes easy to ignore some of the finer points of JavaScripts events.  Two things that I often forget is the difference between the e.target and e.currentTarget properties of the event object that gets passed into a event callback. Hopefully writing this post will help the concepts stick in my head.

The reason we need both of these properties is because of event bubbling.  Event bubbling is when a event travels up the DOM, until it reaches the document node.   Lets say we have a DOM tree that looks like this:

document
|
|--div
|  |
|  |--span
|  |  |
|  |  |--a

Here we have a document node with a child of a div with a child of a span with a child of an anchor.  When the anchor is clicked the any event listeners for the anchor are triggered, then the event bubbles up to it's parent, the span and any of it's event listeners are triggered, then the event bubbles up to the div where its event listeners are triggered, and finally the event bubbles up to the document element where any  of it's event listeners are triggered.

Assuming that the span and div have a margin, padding, and border of 0 whenever a user clicks on the link the event the target property of the event that is triggered on the anchorspan,  div  and document will always be the anchor, since this is where the event originated. The currentTarget property will always be the element that is listening for the event.

The following code shows event listeners on 4 different objects, however when a user clicks on the anchor link the target will be the same for each event listener.



Open up your console and run the following example, paying close attention to the order the events fire as they bubble up the dom:

JS Bin

Wednesday, March 13, 2013

Exploring jQuery Queues

This week I ran into an interesting issue at work. There was an event that was triggered when a custom font loaded that added a fixed position element to an item in a container. Another team wrote some code that caused that container to animate when the page loaded. Sometimes the fixed position element would get placed randomly inside that container because the event was firing before the animation completed. Instead of tightly coupling the animation with the positioning of the element I decided to inspect the animating element's FX queue when the event was triggered to make sure that the element was not in the process of moving when it was added.
Queues in jQuery are a useful way to add a list functions to an element that should be executed in a particular order. The real benefit is that queues give you full control of when each item in the queue is invoked using the dequeue method. If you've used a jQuery animation function you've already used the jQuery fx queue. What a lot of people don't know is that jQuery provides a nice API for inspecting and manipulating queues.

Lets take a look at the typical use case for a jQuery queue; adding multiple animations to an element:



Demo:

JS Bin


When this code is executed each function is invoked one immediately right after the other. However, each animation is NOT performed instantly, each animation is added to the elements fx queue. When each animation is finished the next animation in the queue is invoked.

One interesting thing to note about the fx queue is that calling the stop() method on an element that is animating will only stop the current animation in the queue and immediately call the next animation in the queue. In order to truly stop all of the the animations the element's queue must be cleared as well.
In order to modify the first example to stop all animations when an element is clicked the following code is needed:



Demo:

JS Bin

Delaying And Creating Queues

Custom queues can be created on any elements by passing in a name to the queue call. In addition any queue's execution can be delayed when it is dequeued by using the delay( delayMs, queueName ) method. It's important to note that the delays are added to the queue itself so they need to be added to the queue before the function that you want delayed, however calling dequeue will trigger the delay and invoke the next callback from the queue. This timer will not start until dequeue() is called on the element's queue.

In the following example the queue's execution will be delayed by 1 second, an item will be added to the element, the queue will be delayed by another half second, another item will be appended to the element, the queue is then delayed for another second, and finally another item will be added to the element. The first item in the queue will be invoked in the $.ready() function and each callback in the queue will dequeue the next item in the queue.



Demo:

JS Bin

What makes custom queues with delays an attractive alternative to setTimeout or setInterval is that each item in the queue can have a different delay time before it is invoked.

Wednesday, February 27, 2013

Playing with ECMAScript.Harmony Modules using Traceur

As aI was a preparing a presentation on AMD and RequireJS I started looking ahead at the modules proposed for ECMAScript.Harmony.  In Addy Osmani's article Writing Modular JavaScript With AMD, CommonJS & ES Harmony he mentioned called Traceur which is a JavaScript compiler for ECMAScript Harmony syntax. This allows developers to give the future of JavaScript a test drive today.

One of the new features coming in Harmony that has me excited is modules. Modules will be a way to encapsulate code and explicitly define its dependencies and public API. ES Harmony gives us three new keywords for modules: module, import, and export. The module keyword is used to initialize a new module, the import keyword declares dependencies to import from a module into a context, and the export keyword explicitly declares public properties that will be available for other modules to import.

In addition Harmony modules:
  • are statically scoped
  • have the this keyword bound to the global object

Traceur

Before we are able to write modules today we'll need an environment that supports Harmony syntax. For this we'll use Google's Traceur compiler. In order to implement Traceur you'll need three things:
  1. Traceur library file
  2. Traceur bootstrap file
  3. Harmony code
Adding the Traceur library and bootstrap to an application is as easy as adding the scripts to a web page:



Now that we have a compiler in place we just need some code for it to compile. To do this simply create a script block with a type of script/traceur.



When the page loads Traceur will compile your Harmony code to JavaScript that works in today's modern browsers.

For your convince I've created a JS Bin with Traceur ready to go on JS Bin. In addition there is an online compiler you can use here: http://traceur-compiler.googlecode.com/git/demo/repl.html

Now that we have an environment that supports Harmony to work in lets take a look at modules.

Playing With Modules


First I'd like to point modules aren't meant to be classes, there the class keyword for that. According to the ECMAScript Wiki modules are a
"Standardized mechanism for creating libraries"
Modules do not create a new execution context, the this keyword in a module is bound to the global object. Looking at the code that Traceur outputs for a simple module definition shows this:



Even though a module does not get a new execution context , it does get a new static scope. In the following code I am creating a new module called carFactory that exports a variable named ford into the global namespace. Calling ford.wheels results in '4' and trying to access carFactory's internal wheels variable results in an error:

JS Bin

Its also important to note that doing an import * will import the variables from the modules with the same names the have in the module.

A module can also have multiple exports as shown in the following code (note the syntax for importing multiple exports in a single statement):

JS Bin

A module also doesn't only have to export objects, it can export anything:

JS Bin

Variables that are imported can also renamed the from modules using the following syntax:

JS Bin

Lastly modules can be nexted. Nested modules have privileged access to their parent modules scope. Nested modules are also private to their parent modules scope unless they are explicitly exported. Here is an example of a public nested module that accesses its parents scope:

JS Bin

Conclusion

Modules in Harmony look like they are going to be very useful and there's a lot you can do with them.  They help reduce the need for the overuse of the function keyword and reduce the need for patterns like AMD and complex loaders RequireJS and CurlJS (of which I am currently a huge fan).   For more reading on modules I suggest checking out the modules section on the ECMAScript Harmony WIKI.

Wednesday, October 24, 2012

jsonmé: A Simple HTML and JavaScript Resume Generator

It's been forever since I updated my resumé so I decided to turn my GitHub page into my living resumé.  Being a web developer I wanted to so something unique yet simple.  After playing around with a few concepts I decided to put all of my resume's data into a JSON file and create a small web app that would read it via AJAX and display its contents.  I was so happy with the result that I decided to extract out the code and put it up on GitHub and the result is jsonmé.

I wanted jsonmé to have a small footprint yet work in all browsers back to IE6.  I decided to use the Sizzle.js selector engine since it has such a proven track record in jQuery.  I also needed a small library for doing normalized AJAX requests.  I settled on snack.js, its a small and well written utility library with AJAX capabilities that also gives me a normalized document ready function.  

The resulting application is a simple and easy to implement application.  The easiest way to create your jsonmé is to fork the GitHub repository and rename it to .github.com.  For instance my personal resume is at http://bittersweetryan.github.com.  

The code is completely Open Source and licensed under the MIT license so feel free to grab it and do whatever you want with it.  If you do something awesome with it I'd love to hear about it or even get a pull request for it.

The source can be found at: https://github.com/bittersweetryan/jsonme

Wednesday, October 3, 2012

NCDevCon "The Art of JavaScript" Presentation Links

This is just a real quick post so I can share the link to my NCDevCon presentation slides and video.

The slides can be found at:

http://bittersweetryan.github.com/art-of-javascript/

The video can be found at (sorry, its in Silverlight format only):

http://textiles.online.ncsu.edu/online/SilverlightPlayer/Default.aspx?peid=02c7fe6174654f96b78a6194d3dbbe9d1d

One more thing, I was mentioned in the KeyNote!  You can watch that here, I'm mentioned in the second section about: "ColdFusion Today":

http://textiles.online.ncsu.edu/online/SilverlightPlayer/Default.aspx?peid=9c64b0db237e4240847875f95795138d1d

Please if you enjoyed let me know, or if you have any questions or suggestions how I can make this presentation better please let me know!

Tuesday, September 4, 2012

jQuery Function Of The Week: Deferred (deep dive)

This week we'll take a deeper look into jQuery's Deferred object.  According to the jQuery docs:
jQuery.Deferred(), introduced in version 1.5, is a chainable utility object that can register multiple callbacks into callback queues, invoke callback queues, and relay the success or failure state of any synchronous or asynchronous function.
That is a bit of a mouthful.  I like to think of deferrds somewhat like a telephone call.  You'd like to contact someone so you dial a number.  Based on what happens when you call that number you will take action.  If the callee answers the call you can start a conversation, if you get their voice mail (I almost said answering machine but I'm afraid that some readers will have no idea what that is) you can take leave a message.  Also, when the phone is ringing you can even do something else, you only care about what happens once the number you are calling responds in some way.  This is an extremely simplified way of describing how Deferreds work because Deferrds can do so much more.

If you've used jQuery's AJAX functions you've already been taking advantage of Deferreds, the AJAX functions are actually using Deferrds behind the scenes with a lot of the details abstracted out for you.

When talking about Deferreds its important to note that there are two parts to each Deferred implementation: the callers and the callees.  The callers are the functions that either do something that other functions are waiting for or functions that take action based on the results of another function.  The callees are the functions that depend on the results of at least one of the callee functions.

The Callers

Like I mentoned before, the caller functions are divided into two parts: the functions that do something that other functions depend on, and the functions that take action based on the the results of other functions.  The when(deferrds)function is the first part of the callers and is a wrapper for all of the functions have results that other functions are waiting for.  jQuery will execute the functions passed into when immediately and asynchrouously.  This means if we have the following code:

func1(), func2(), and func()will all be called at approximately the same time.  

Functions passed into when are expected to return a promise object back to the when() function.  This promise will either be resolved or rejected (more on these in the callees section) by the function passed into when, and based on this result one of callback functions will be called.  

The second part of the callers are the functions that respond to the results of the functions passed into the when function.  The three functions are: then, done, and fail.  The then(doneCallbacks, failCallbacks) is a single method that encapsulates the functionality of the done() and fail() callbacks.  The first argument to the then function is a function, or array of functions, that will be called when all the functions passed into the when() function are resolved.  

The second argument passed into the then function is a function, or array of functions, that will be immediately invoked as soon as any of the functions passed into the when() function are rejected  The then and done functions will receive arguments from each function passed into the when function, in the order they were passed.   These arguments are passed into them via the resolve and reject methods (we will talk about when we discuss the callees).  If you'd like to be a bit more expressive in your code instead of using the then() you can specify the doneCallbacks and failCallbacks in the done() and fail() methods.  These methods are called the same was as the doneCallbacks, and failCallbacks of the then() function.

The Callees

When functions are passed into the when function jQuery expects these functions to return a promise to it.  A promise is just a message telling the when function that sometime in the future the function is either going to send it a  reject( args ) or resolve( args ) message.  Once the when function receives the promise object from a function it just sits and waits for a response.  The callee functions can also pass information back to the when function by passing arguments into the reject and resolve methods (I'll show you an example of this in the real world example).  Lets take a look at a typical callee function that implements the Deferred object and talk a bit more about what is going on:

Here we have a function that is going to implement the $.Deferred() function and immediately return a promise message to the when() function that called it.  The $.Deferred() constructor  function takes an optional function as an argument which is passed a reference to itself as an argument.    The above function could also have been rewritten as: 

Its important to note that if a function passed into when does not implement this Deferred pattern it will immediately be treated as resolved.

Real World Example

Now that we've looked at the parts of the Deferred lets take a look at a real world example.  In order to demonstrate the power of Deferred's lets take a look at some code that can benefit from them:
JS Bin

The intent of this code is to fade out any current content, get some tweets from twitters search API, and finally display the new tweets.  When any of the buttons are pressed you'll quickly see that something isn't right, and this is because the code being called relies on asynchronous operations like doing an AJAX call and jQuery animations.

One approach to fix this would be to put the getTweets function as a callback to the cleanDiv function's fadeOut callback, move the addTweets function to the ajax calls success callback, and finally move the the $tweetDiv.fadeIn('slow') code to the addTweets function. Doing so would tightly couple this code together making it tough to extend and maintain.  A better solution would to use the power of jQuery's Deferred object.

First lets look at our click handler function rewritten to take advantage of the Deferred object:



The first thing you probably notice is that there is more code in the new click handler.  The Deferred calls do add a bit of code, but I feel this code is quite expressive (meaning that the intent of the code is very clear) and each of the callback functions are decoupled from any function they are waiting on.  One other thing to note here is the use of the done() and fail() callbacks.  In the done() callback I use the when() and then() methods of the Deferred implementation.  Here I am only specifying a  single argument which will get called if/when the addTweets function passed into it has completed.  Since I'm not going to reject the promise anywhere in the addTweets function only passing in a done callback is sufficient.

Now lets take a look at one of the new callee functions.  Here is the code for the new getTweets function:



Since there is no access to the internal representation of the $.ajax method's Deferred function I have to wrap the entire function in a Deferred call.  Another thing to note is that Twitter's API will return a 200 status (which will invoke the ajax function's success callback) even if there is an error so  I will inspect the object returned from Twitter when determining weather to resolve or reject the Deferred object.  If a key of "error" is found in the data returned from Twitter I reject the Deferred which tells our click handler function to run the fail callback.  I'll also pass a message to the fail callback through the reject method call.


Putting it all together we get a nice and smooth implementation of our application.  As you can see I've also included an error button which will trigger an error in the twitter API.

JS Bin

Tuesday, August 14, 2012

jQuery Function of the Week: grep

This week's jQuery function of the week is grep.  According to the jQuery docs grep:
Finds the elements of an array which satisfy a filter function. The original array is not affected.
There is only a single signature for the grep function: $.grep(array, function(element, index) [,invert]). The function being passed in should return a truthy value or a falsy value based on the input argument.  If the invert parameter is left out, or is false then the grep function will return a new array with all the items that the satisfy the truth test function that was passed in.  If invert is set to true, grep will return a new array with all the items that do not satisfy the truth test function.

Lets take a look at looping through an array of text and removing the word "the":

JS Bin demo

Now lets take a look at the same code, but with the invert parameter set to true:

JS Bin demo

You'll see that only the word "the" is returned.

Check out the all of the jQuery function's of the week.

Thursday, August 9, 2012

jQuery Function Of The Week: nextAll

I'm super busy this week so this week's jQuery function of the week is going to be an easy one: nextAll.  According to the jQuery Documentation use nextAll to:
Get all following siblings of each element in the set of matched elements, optionally filtered by a selector.
Lets say we had a list of items, and we wanted to highlight every vegetable  Using nextAll would look like this:

JS Bin demo

Optionally a selector can be passed into nextAll to further filter the results.  Here we'll only select the even vegetables that are after our original selector:

JS Bin demo

Wednesday, August 1, 2012

jQuery Function Of The Week: proxy

In my JavaScript fundamentals presentations I have a section that talks about scope and how it can become confusing when using jQuery.  The reason for this is becuase jQuery normalizes the this scope in its function calls.  In other words when inside a jQuery method call this usually refers to the DOM elements in the jQuery set.

This can be clearly illustraed in a simple jQuery event callback (note use your browsers console, not jsbin's for the meantime):

JS Bin demo

This can become a problem when we try to write reusable code. Lets say we want to put our event handler into a object and then call it when a user clicks on a link:

JS Bin Demo

If you run the code you'll see that you get "Hello, undefined" instead of "Hello, Homer Simpson". The reason is simple, jQuery used the link as the context of this where no myName property exists. Enter jQuery.proxy.

According to the jQuery Documentation, the proxy function:
Takes a function and returns a new one that will always have a particular context.
This means that by using the $.proxy function we can make our callback run in the proper context, in this case itself:

JS Bin Demo

The change is subtle, but the result is exactly what we want.   Now, at this point you might be asking yourself, "isn't this the same thing as using the apply() or call() methods (mdn apply documentation)?   The answer is yes...and no.  Lets look at how to get the desired result using apply():

JS Bin Demo

If you look closely you'll notice a slight difference, the callback is now invoked in an anonymous function instead of passed directly to the on() method.  This is because the apply method invokes the function immediately whereas jQuery's proxy function only returns a reference function for later invocation.   This is a bit nicer because it makes for slightly more terse code.

In addition the proxy() function does a few more things:

  • it makes sure that the function passed in is actually a function
  • it assignes a unique ID to the function.  This is very important because when trying to unbind a function you may not be unbinding the proper function if you are passing in the function to the off() method.  Its best to always use namespaced events when using on() and off() with $.proxy().

Friday, July 27, 2012

Solving JavaScript Async Issues the Easy Way, With Events

By now we all know that JavaScript is asyncronous and what that means, right?  If not the following code will help explain the concept in 30 seconds:


This code will run function a() then b(), even if the ajax request in a() has not yet completed.

There are a lot of approaches that can be used to make sure that b only runs when a is done.  One approach would be to use jQuery deferreds like so:


We can also use a async library, such as q, if we need a bit more power.  Or we can use JavaScript's setTimeout(func, delay) function to continuously check for a variable the function a() sets when it is done before we call b(), how awful does that sound? In some cases there is a quite simple way to achieve this, by using events.  I might even argue that using events is the more JavaScripty way to do things in the right situation.  Lets take a look at the a/b example, this time using events:


Lets take take a look at a real world example of using events to make sure things happen in the proper order.  Here we will use a backbone collection as a wrapper for a one or more Contact objects that will be reused in multiple places in an application:


Let say we want to use this collection to populate a drop down when a view is initialized like so:


Using this code there is a good chance that the models will be an empty array when we try to add them to the dropdown.  Also, when the collection's fetch() completes the app.contacts.models array will be reset, meaning that the reference to the contacts in your view likely will not reference the current app.contacts.models array.

To fix this, lets first update our collection to trigger an event when the contacts are loaded.  In this example I'm going to use jQuery's trigger(eventName) function to keep things easy:


The last step is to make sure we are adding the carriers to the drop down after they have been added to the collection. To do this we just need to add an event listener to our initialize function:



Now we will always be working with a populated collection in our addContacts method.

Monday, July 23, 2012

jQuery Function Of The Week: one

jQuery's one function is an extremely useful function when you want an event to fire exactly one time.   According to the official jQuery documentation use one to, "Attach a handler to an event for the elements. The handler is executed at most once per element"  One is a much more terse way of setting an event handler and calling unbind() or off() in the handler function.

The easiest use of one is to pass it an event and a handler like so:



Click Here to Demo on JS Bin

You can click the link as many times as you wish, however the event will only fire once.

You can pass in more than one event handler to the one function by passing in a list of events separated by a space.  When you do this each event will fire once.  In this example the event will fire 3 times, one time for each event:



Click Here to Demo on JS Bin

You can also  pass in custom data to the event handler, the data comes attached to the event.data object like so:



Click Here to Demo on JS Bin

One additional thing you can do with the one function is use an additional selector to pass into the one event that will attach the event to exactly one of the descendants of the matched set. In the following example click on any of the li elements, then click on another, you'll see the event only fires for the first element selected.



Click Here to Demo on JS Bin

Check out the all of the jQuery function's of the week.


Wednesday, July 18, 2012

Playing Around With JavaScript's stopPropagation and preventDefault Methods

While playing around with pure JavaScript events lately I created this jsfiddle to demonstrate the concepts of the event methods preventDefault() and stopPrpagation().  While you are playing with it make sure to have your Browser's console open so you can see the debugging output.

The preventDefault() method on an event, does exactly that, prevents the event's default behavior.  In this instance it stops an <a> element from going to the link.  The stopPropagation() method stops the event from bubbling up DOM nodes.  In this case we have an <a> link nested in a <span> that is nested in a <div>.  When a user clicks on the <a> the event is triggered on that element, then the span, then the div, all the way up the DOM until it reaches the document node.  Calling stopPropagation() on the <a>'s click event only triggers the event on the <a> element  and none of its parent nodes.  

Tuesday, February 28, 2012

My Argument Against ColdFusion Sucks & Other Related Putdowns

While I was driving home last week I listening to the "Hearding Code" podcast with Chris Williams (the organizer of jsconf) and I had a small revelation.   Chris brought up how coders will use up one bad experience with a language to completely write it off and publicly denounce the it every chance they get.  Raise your hand if this immediately makes you of think of ColdFusion.   Me too.

Then I started thinking, JavaScript is one of the hottest languages around right now, and for good reason, it has evolved tremendously from where it was in the late 90's.  Does that remind you of anything?  If you are a ColdFusion developer it should seen very familiar to the language you use every day.  Anyone who writes modern ColdFusion code will likely cringe at the code they wrote back in the pre-MX days, just like a lot of the JavaScript developers did in the pre-jQuery/Dojo/Sencha/Prototype/MooTools days.

Next time we hear someone publicly call out ColdFusion for a one bad experience they've had with an app that was written in the late 90's early 2000's lets remind them about JavaScript and the many bad experiences we've all had with it back in its early days.  Lets also remind them how it has evolved into one of the most popular languages in the world.

ColdFusion, in my opinion,  has evolved just as much as JavaScript.  We have a great testing framework in MXUnit, lots of great MVC frameworks to chose from, and a number of other great frameworks that help us be productive such as Validate This, ColdSpring, Hoth, and Hyrule to name a few.  These are all advanced programming frameworks that weren't around in the early days.  In additon ColdFusion itself has also come a really long way as a programming language.  We can how write code in a way that many programmers consider much more elegant and terse with the script updates in ColdFusion9.   We can also use really powerful techniques like onMissingMethod, dynamic typing, and treating functions as first class citizens.  We have ORM capabilities baked right in the framework, how cool is that?!?

While agree it has taken ColdFusion a long time to get this far while languages like Ruby, Python, and even PHP have progressed at a bit faster rate its good that we have gotten where we are.  With the upcoming release of Zeus ColdFusion will take another step further with HTML5 controls built in, RESTful interfaces, closures, and a bunch more exciting features.  These are exciting times to be a ColdFusion developer and I hope that we can advocate the language moving forward by drawing parallels to other languages, like JavaScript,  that have had rough beginnings but are now considered "cool" languages.

Thursday, October 13, 2011

Using the JavaScript "this" Keyword In 3 Common Patterns

I'm not breaking any ground here, everything in this post has been discussed before. However, I like to write about things I want to understand better hence the main reason for this post. In this post I'll take a deeper look at using the "this" keyword in three common patterns: Object Literals, Modules aka IIFE's (sometimes called self executing anonymous functions), and Constructor functions. This acts a little differently in all three of these scenarios and I've spent some time on jsfiddle playing with each.

Object Literals

First lets take a look the most straight forward pattern (I know it's not really a pattern but its still a way some developers use to organize their code): the object literal.  In the object literal "this" points to the object's properties, in fact, you have to use "this" to refer to any of the objects.  One important thing to note here is that nested functions DO NOT have access to the objects "this" scope.  Look at the sayHello function in the code below, notice that there is an inner "helper" function.  Trying to access "this" within it would refer to the window object and not the person object.  In order to provide access to "this" a common workaround is to create another variable that points to "this".  Here I'll call it "self".

//this and objects
var person = {
    firstName: "Ryan",

    lastName: "Anklam",

    getFullName: function() {
        //inside an object we need to point to this to access its properties
        var firstName = "Yoko"; //this var is local to the function so, but 'this' still outputs Ryan
        return this.firstName + ' ' + this.lastName;
    },
    
    sayHello : function(){
        var self= this;  
        var inner = function(){
            //this inner function doesn't have privlaged access to the object's vars.  "this" in here actually refers to the "window" object
            return self.getFullName() + " says hello";
        };
       
       return inner(); 
    }
};

http://jsfiddle.net/bittersweetryan/wewY4/

IIFE's / Modules
In the module pattern things get interesting since the context of "this" is really the "window" context,  however, one of the common ways to provide public members to an IIFE is to return an object with public functions.  As we discussed before there is a "this" scope within the object literal. Since everything is nicely encapsulated in the IIFE the object can directly access it's parent function's variables.

var person = (function(){
    var firstName = "Gregg";
    var lastName = "Jennings";
    
    return{
        getFirstName : function(){
            return firstName + ' ' + lastName;
        },
        
        sayHello : function(){
            return this.getFirstName() + " says hello";
        }
    };
})();

One interesting twist that I first saw on Ben Nadal's blog post "Decoding Morse Code With JavaScript" was to use the call() method when invoking the IIFE and passing in a new object for the context of this. What I really like about this approach is that we don't have to return a new object literal, we can just return "this" to provide public access to methods that are assigned to the "this" scope.

var person = (function(){
    //these are private still
    var firstName = "Aaron";
    var lastName = "Rodgers";
    
    //this will be made public by returning this (see the end of the person function to see where this is coming from
    this.getFirstName = function(){
            return firstName + ' ' + lastName;
    };
        
    this.sayHello = function(){
            return this.getFirstName() + " says hello";
    };
              
    return this;
}).call({});  //sweet! we can set this in an IIFE by passing in a blank object literal using the call method

http://jsfiddle.net/bittersweetryan/qzkzy/

Constructor Functions

When dealing with Constructor functions you should be very careful. The "this" context will ONLY exist after a new instance of the constructor is created using the new keyword. Once the new keyword is used to create a new object only functions that are assigned to the "this" context will be made public. In the example below the sayHello function will only be available after the new keyword is used to create a new instance of the function.

//this and a prototype
function Person(){
    var firstName = "Chales";
    var lastName = "Woodson";
    
    //private within Person object
    function getFullName(){
        return firstName + ' ' + lastName;       
    };
    
    //public function that returns the firstName and lastName
    this.sayHello = function(){
        return getFullName() + " says hi";
    }
};

//this will throw an error since it tries to access a property in the this scope which isn't defined without using new
//console.log(Person.sayHello());

var newPerson = new Person();
console.log(newPerson.sayHello());

http://jsfiddle.net/bittersweetryan/45ceQ/

Monday, September 26, 2011

Serialize Your CFC's Getters Into JavaScript Objects With CF PB&J

This weekend I worked on a little project called CF PB&J that will serialize a CFC's getters and their output into a well-encapsulated JavaScript object.  It's meant to be lightweight and work seamless with your JavaScript  while not cluttering up your global by having to create a  bunch of global variables to store your dynamic data.  You can find the project up on github at https://github.com/bittersweetryan/CF-PB-J.

Lets take a look at a quick example of how it works.  First lets create an Account object (note that there would typically be setter methods for these functions as well but they are left out for brevity's sake):

<cfcomponent hint="Test very simple cfc for searalization to javascript">
	<cfscript>
		variables.accountNumber = 0;
		variables.accountName = "";
		variables.productArray = [];
		variables.insuredProducts = {};
		
		
		variables.PBJ = "";
	</cfscript>
	
	<cffunction name="init" returntype="Account" access="public" output="false" hint="" >
		<cfscript>
//create the PBJ object and pass in a reference to this
			variables.PBJ = createObject("PBJ").init(this);
			return this;
		</cfscript>
	</cffunction>
	
	<cffunction name="getAccountNumber" returntype="numeric" access="public" output="false" hint="" >
		<cfscript>
			return variables.accountNumber; 
		</cfscript>
	</cffunction>
	
	<cffunction name="getAccountName" returntype="String" access="public" output="false" hint="" >
		<cfscript>
			return variables.accountName; 
		</cfscript>
	</cffunction>
	
	<cffunction name="toJS" returntype="String" access="public" output="false" hint="Proxy to the PBJ toJS method" >
		<cfscript>
			return variables.PBJ.toJS();
		</cfscript>
	</cffunction>
	
	<cffunction name="getProductArray" returntype="Array" access="public" output="false" hint="" >
		<cfscript>
			return variables.productArray;
		</cfscript>
	</cffunction>


	<cffunction name="getInsuredProducts" returntype="Struct" access="public" output="false" hint="" >
		<cfscript>
			return variables.insuredProducts;
		</cfscript>
	</cffunction>
	
</cfcomponent>

If you look closely at the Init method you'll see that a PBJ object is created and initalized and the "this" reference is passed to it.  This tells PB&J to inspect the current object for its "getter" methods defined by the naming convention getXXX.  PB&J will look for all getter methods that return strings, numbers, arrays, and structures.  This object also defines a proxy function called "toJS"that calls the PBJ.toJS() method.  When this method is invoked it will run all of your object's getter methods, save the return data, and output JavaScript that is a mirror of your object with its getter methods and its data.  Lets take a look at an example of this in action.  First lets create an instance of the account object and set some of its data:

account = createObject("Account").init();
	
account.setAccountNumber(12345);
account.setAccountName("Ryan ""Pretty Boy"" Anklam");

Now in our .cfm page we output the value of  #account.toJS()#  in the header to produce our JavaScript representation of our object:

< script type = "text/javascript" charset = "utf-8" >
var Account = (function() {
    var accountName = "Ryan \"Pretty Boy\" Anklam";
    var productArray = [];
    var insuredProducts = {};
    var accountNumber = 12345;
    return {
        getAccountName: function() {
            return accountName;
        },
        getProductArray: function() {
            return productArray;
        },
        getInsuredProducts: function() {
            return insuredProducts;
        },
        getAccountNumber: function() {
            return accountNumber;
        }
    };
})(); 
< /script>

Looking at the JavaScript you'll see that CF PB&J created a few private variables and returned public methods to return that data.   It's meant to be a "read-only" representation of the internal state of your object.  PB&J will also work on calculated fields as it just invokes your getter methods and saves its output.

Now in any of your scripts you can access the object's data by calling the JavaScript object's getter methods:

< script type = "text/javascript" charset = "utf-8" >
     Account.getAccountName();
     Account.getAccountNumber();
< /script>

Wednesday, August 10, 2011

Learn JavaScript completely On the Cloud With the JavaScript Koans and Cloud9 IDE

Lately I've been investing a lot of time into learning JavaScript and one of the neatest things I've come across is the JavaScript Koans project.  If you haven't heard of Koans before the basic concept is to learn a programming language through the act completing unit tests in that language.   The most popular implementation of this concept is the Ruby Koans project (http://rubykoans.com/).  Liam McLennan took this concept and ported it over to JavaScript and his implementation can be found over on github (https://github.com/liammclennan/JavaScript-Koans).

When you pair this repository with the Cloud9 IDE you can work on them completely on the cloud without having to download a single piece of code locally.  Cloud9 (http://cloud9ide.com/) is an completely online and very richly featured IDE.  One of the great things about Cloud 9 is that it can access your github repositories and clone them into its environment for you to edit.  Cloud9 also provides you with a interactive console with git installed so you can push the changes back into your repository. The console will even give you intellisence on the git commands as shown to the right!

Assuming you already have a github account the first step is to fork a copy of the JavaScript Koans repository.  Once you have a forked copy of the Koans head over to the Cloud9 website and log into your dashboard.  Your dashboard will have a "Add On Services" section that will allow you to connect Cloud9 with your github account and pull in your public repositories.  One thing I've noticed is that if you've added a new repository since you last connected with github you'll have to connect to github again for Cloud9 to pull in the newly created repository.   Once the repository is pulled into Cloud9 next you'll have to select the project from the github menu and click on the "Clone to Edit" in order to be able to edit the files.

Once your github repository is cloned it will show up as a new project in the Projects area.  First click on the Koans project and click on the "Start Editing" button which will open up the project in a new tab.   Once your koans project is open double click on the "jskoans.htm" file to open it up in the editor.  The editor will detect that this is a HTML file and a "preview" icon will appear in the editor.  Click on this button to run the Koans.  When you do the jskoans.htm file will open in a new tab and run the koans unit tests, which will fail on the first test like so:



Whats important to note here is which file the error occurred on. The Koans are organized by topics, and each topic will have its own JavaScript file with qUnit tests that pertain to that topic.  Find that file that caused the error in the editor and open it.  You'll now see all the qUnit tests for that file.  Below you'll see the code from the first topic which is a brief overview of assertions.


Inside the assertion code there will always be two underscores "__" that denote an area where you are to fill in a value to make the test pass.  As you go through the exersizes save the unit test file and refresh the jskoans.htm preview page and you'll start to fill the page with passed tests.  The test runner will stop at the first failed test it finds. As more and more of the tests pass the page will begin to fill up with passed tests as shown in the image to the right.

Whats great about the koans is that its an open source project so community members can add more tests and actively improve the tests that are there, which are very good right now.  Some of the topics covered are: arrays, reflection, prototypical inheritance, objects, and functions and closures. Going through these you'll get to learn JavaScript the best way, by writing JavaScript.




Fork me on GitHub