An intro to Javascript promises

Promises are the new way™ to express "Do this, and once you're done, do that". In contrast to callbacks, promises are easily chainable. From the readme of Q, an early implementer of the pattern:

The callback approach is called an “inversion of control”. A function that accepts a callback instead of a return value is saying, “Don’t call me, I’ll call you.”. Promises un-invert the inversion, cleanly separating the input arguments from control flow arguments. This simplifies the use and creation of APIs, p...

A tracer utility in 2kb « JavaScript, JavaScript

Inspired by a snippet of code in Oliver Steele’s legendary Functional library, here’s a lightweight tool to help keep track of JavaScript invocations. It works in Chrome, Safari, Firebug and IE8.

Unobtrusive JavaScript and AJAX

Attached (see below) is some code to allow using unobtrusive JavaScript on pages fetched with an AJAX call.

After you included it, you now do not use the usual

$(function() { 
  $('.some_tag').activateStuff(); 
});

any more, but instead you write

$.unobtrusive(function() {
  $(this).find('.some_tag').activateStuff();
});

that is

  • $.unobtrusive() instead of $()
  • don't do stuff to the whole page, but just to elements nested below $(this)

Normal pages work as before (your $.unobtrusive functions are ca...

Mocking time in Jasmine specs

The easiest way to freeze or travel through time in a Jasmine spec is to use the built-in jasmine.clock().

  • After jasmine.clock().install() you can use it to control setTimeout and setInterval.
  • Using jasmine.clock().mockDate() you can mock new Date() (which returns the current time in Javascript)

While you can use SinonJS Fake timers, using the built-in Jasmine clock will save you an extra dependency.

JavaScript events: target vs currentTarget

tl;dr: Use event.currentTarget unless you are absolutely certain that you need event.target.


Since it hasn't been written down in this deck before, here it goes:

When working with JavaScript Event objects, the DOM element that triggered the event is attached to them. [1]
However, there are 2 "opinions" on which element that would be:

  • The element that the user interacted with (event.target),
  • or the element that the event listener is bound to (event.currentTarget).

Note that both can be, but not...

Enable CSRF protection in Javascript tests

You might not know that Rails disables CSRF protection in tests. This means that if you accidentally forget to send the CSRF token for non-GET requests, your tests will be green even though your application is completely broken (a failed CSRF check usually logs out the user). Rails probably does this because CSRF protection sort of requires Javascript.

You want to enable CSRF protection in Cucumber scenarios that can speak Javascript. To do so, copy the a...

JavaScript: How to check if an object is NaN

JavaScript's NaN ("Not a Number") is hard to compare against. It never equals anything, not even itself:

NaN === NaN;        // false
Number.NaN === NaN; // false

There is the isNaN method, but it is not really what you are looking for:

isNaN(NaN)     // true
isNaN('hello') // true

Option 1: ES6

The Object.is() method determines whether two values are the same value. It even works for NaN:

Object.is(NaN, NaN) // true

Option 2: ES5

The example above shows that simply using isNaN would match other ...

The Easiest Way to Parse URLs with JavaScript

A very clever hack to parse a structured URL object is to create a <a> element and set its href to the URL you want to parse.

You can then query the <a> element for its components like schema, hostname, port, pathname, query, hash:

var parser = document.createElement('a');
parser.href = 'http://heise.de/bar';
parser.hostname; // => 'heise.de'
pathname = parser.pathname; // => '/bar'

if (pathname[0] != '/')
  pathname = '/' + pathname // Fix IE11

One advantag...

Represent astral Unicode characters in Javascript, HTML or Ruby

Here is a symbol of an eight note: ♪

Its two-byte hex representation is 0x266A.

This card describes how to create a string with this symbol in various languages.

All languages

Since our tool chain (editors, languages, databases, browsers) is UTF-8 aware (or at least doesn't mangle bytes), you can usually get away with just pasting the symbol verbatim:

note = '♪'

This is great for shapes that are easily recognized by your fellow programmers.
It's not...

JavaScript: How to generate a regular expression from a string

Getting a regular expression from a string in JavaScript is quite simple:

new RegExp('Hello Universe');
# => /Hello Universe/

You can also use special characters:

new RegExp('^(\\d+) users')
# => /^(\d+) users/

Our expression above now works only at the beginning of the matched string, looks for a number (\d+ [1]) and also captures that. Sweet.

However, mind that your input will not be magically escaped because of that:

new RegExp('makandra.com')
# => /makandra.com/

The above expression would match "`...

Single step and slow motion for cucumber scenarios using @javascript selenium

Single step and slow motion for Cucumber scenarios can come in handy, especially in @javascript scenarios.

# features/support/examiners.rb
AfterStep('@slow_motion') do
  sleep 2
end

AfterStep('@single_step') do
  print "Single Stepping. Hit enter to continue"
  STDIN.getc
end

If you're using spreewald, these tags are available as @slow-motion and @single-step (with dashes instead of underscores).

Note: You can also [prevent the selenium webbrowser wind...

Javascript equivalent of Ruby's array.collect(&:method)

The most common use case for Ruby's #collect is to call a method on each list element and collect the return values in a new array:

['hello', 'world', 'this', 'is', 'nice'].collect(&:length)
# => [5, 5, 4, 2, 4]

Although there is no equivalent to this idiom in naked Javascript, there is a way to collect object properties (but not method results) if you are using common Javascript libraries.

If you are using jQuery with the Underscore.js utility library, you can use [pluck](htt...

Asset pipeline may break Javascript for IE (but only on production)

If some of your JavaScripts fail on Internet Explorer, but only in staging or production environments, chances are that JavaScript compression is the culprit.

By default, Rails 3.2 compresses JavaScript with UglifyJS. I have seen a few cases where this actually breaks functioning JavaScript on IE (one example is the CKEditor).

I fixed this by switching to Yahoo's YUI Compressor.

To do this, do the following:

  • replace the uglifier gem with the yui-compressor gem...

Convert primitive Ruby structures into Javascript

Controller responses often include Javascript code that contains values from Ruby variables. E.g. you want to call a Javascript function foo(...) with the argument stored in the Ruby variable @foo. You can do this by using ERB tags (<%= ruby_expression %>) or, in Haml, interpolation syntax (#{ruby_expression}).

In any case you will take care of proper quoting and escaping of quotes, line feeds, etc. A convenient way to do this is to use Object#json, which is defined for Ruby strings, numb...

Compiling Javascript template functions with the asset pipeline

The asset pipeline (which is actually backed by sprockets) has a nice feature where templates ending in .jst are compiled into Javascript template functions. These templates can be rendered by calling JST['path/to/template'](template: 'variables'):

<!-- templates/hello.jst.ejs -->
<div>Hello, <span><%= name %></span>!</div>

// application.js
//= require templates/hello
$("#hello").html(JST["templates/hello"]({ name: "Sam" }));

Whatever is in the <% ... %> is evaluated in Javascript...

Pierce through Javascript closures and access private symbols

If you are writing any amount of Javascript, you are probably using closures to hide local state, e.g. to have private methods.

In tests you may find it necessary to inspect a variable that is hidden behind a closure, or to mock a private method using Jasmine spies.

You can use the attached Knife helper to punch a hole into your closure, through which you can read, write or mock local symbols:

klass = (->

 privateVariable = 0

 privateMethod = ->
   ...

Dealing with "TypeError: Converting circular structure to JSON" on JavaScript

JavaScript structures that include circular references can't be serialized with a"plain" JSON.stringify. Example:

a = { name: 'Groucho' };
b = { name: 'Harpo', sibling: a };
a.sibling = b;

Doing a JSON.stringify(a) will throw an error:

TypeError: Converting circular structure to JSON

There is not much you can do about that except specifying a custom serializer function that detects and cleans up circular references. There are existing solutions so you do not need to think of one yourself, like <https://githu...

Unobtrusive jQuery to toggle visibility with selects and checkboxes

Use this if you want to show or hide part of a form if certain options are selected or boxes are checked.

The triggering input gets an data-selects-visibility attribute with a selector for the elements to show or hide, like

<%= form.select :advancedness, [['basic', 'basic'], ['advanced', 'advanced'], ['very advanced', 'very_advanced]], {}, :"data-selects-visibility" => ".sub_form" %>

The elements that are shown/hidden look like

<div class="sub_form" data-show-for="basic"> 
  only shown for advancedness = basic 
</div>

...

How to human-join an array in JavaScript

To simulate Rails' to_sentence in your JavaScript application, you can use these few lines of CoffeeScript code:

joinSentence = (array) ->
  if array.length > 1
    array[0..-2].join(', ') + ', and ' + array[-1..]
  else
    array.join ', '

Examples:

> joinSentence(['cats', 'dogs', 'pandas'])
# => 'cats, dogs, and pandas'

^
> joinSentence(['llamas'])
# => 'llamas'

Here is some plain JavaScript, should you prefer that:

function joinSentence(array) {
  if (array.length > 1) {
    return ar...

The Plight of Pinocchio: JavaScript's quest to become a real language - opensoul.org

Great presentation about writing Javascript like you write everything else: Well-structured and tested.

JavaScript is no longer a toy language. Many of our applications can’t function without it. If we are going to use JavaScript to do real things, we need to treat it like a real language, adopting the same practices we use with real languages.

This framework agnostic talk takes a serious look at how we develop JavaScript applications. Despite its prototypical nature, good object-oriented programming principles are still relevant. The...

Less.js Will Obsolete CSS

Less.js is a JavaScript implementation of LESS that’s run by your web browser. As any JavaScript, you include a link to the script in your HTML, and…that’s that. LESS is now going to process LESS code so instead of including a link to a CSS file, you’ll include a link directly to your LESS code. That’s right, no CSS pre-processing, LESS will handle it live.

JavaScript: Hash/Object with default value

You can easily have a JavaScript hash/object that returns a default value for unset keys/properties -- as long as you need to support only recent browsers.

The key are JavaScript proxies from ECMAScript 6 that allow implementing a custom getter method. They work like this:

var hash = new Proxy({}, {
  get: function(object, property) {
    return object.hasOwnProperty(property) ? object[property] : 'hello';
  }
});

When you set a key,...

sstephenson/execjs - GitHub

ExecJS lets you run JavaScript code from Ruby. It automatically picks the best runtime available to evaluate your JavaScript program, then returns the result to you as a Ruby object.

Thoughtbot's experiences with headless Javascript testing

Selenium has been the siren song that continually calls out to us. Unfortunately, in practice we’ve been unable to get Selenium to run reliably for real applications, on both developers machines and on the continuous integration server. This failure with Selenium has caused us to search for alternative solutions