Pivotal Labs

Main menu

Skip to primary content
Skip to secondary content
  • About
  • Case Studies
  • Team
    • Executives
    • Locations
      • San Francisco (HQ)
      • Boston
      • Boulder
      • Denver
      • London
      • Los Angeles
      • New York
  • Community
    • Blogs
    • Tech Talks
    • Events
  • Careers
    • Lifestyle
    • Principles & Practices
    • Benefits
    • FAQ
    • Apply
  • Contact
    • Press Room
    • Press Releases
    • In The News
    • Press Kit
  • All
  • Labs
  • Standup
  • Tracker
Mark Rushakoff

How I remember the difference between Function.call and Function.apply

Mark Rushakoff
Tuesday, September 4, 2012

In Javascript, when you use a function as a first-class-object, you can call the function directly without any special context:

 function execute(func) {
     func();
 }

where the context is the value of this in the function when it’s executed.

If you’re not invoking the function with any arguments, it doesn’t really matter whether you use .apply or .call:

function execute(func, context) {
    // these two statements have the same effect
    func.call(context);
    func.apply(context);
}

But as soon as you need to pass arguments…

 function executeWith123(func, context) {
    // these two statements also have the same effect
    func.call(context, 1, 2, 3);
    func.apply(context, [1, 2, 3]);
 }

The difference is that with call, you can write as many arguments as you need, which is handy when you know exactly which and how many arguments you’re passing. With apply, it’s easier to use a variable number of arguments.

I used to have to always look up the difference between call and apply, until I realized:

Function.apply takes an array: A is for Apply and Array.

I hope that saves you the pain of looking up the documentation or guessing and picking the wrong one next time.

  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Ben Moss

Running JSHint from within Jasmine

Ben Moss
Wednesday, August 22, 2012

I often find myself wasting a lot of time debugging a mysteriously failing Jasmine spec, only to find the root cause being some missing semicolon, the accidental use of double-equals equality or some similar Javascript eccentricity hiding inside my code. On my current project we had been using JSHint through the jslint_on_rails gem to lint our Javascript as part of our test suite, but the unfortunate part of that is that it’s outside of our normal TDD cycle, functioning more like a style enforcer than something that can actually help you find bugs.

To help with getting more instant feedback, I wanted to see if we could get JSHint to run against our code from within the Jasmine test suite itself. I came across this blog post from Brandon Keepers describing how he does exactly that.

One gotcha I ran into was that I had a number of global objects defined in my specs both by Jasmine and several libraries we were using. JSHint defines some options for whitelisting common globals in its docs under “Environments”, but does a poor job of explaining how to whitelist additional variables. I discovered that by passing an object literal of globals as a third argument to the JSHINT function, I could exempt these from definition warnings.

A partial list of ones I’ve so far found handy:

var globals = {
   _: false,
   _V_: false,
   afterEach: false,
   beforeEach: false,
   confirm: false,
   context: false,
   describe: false,
   expect: false,
   it: false,
   jasmine: false,
   JSHINT: false,
   mostRecentAjaxRequest: false,
   qq: false,
   runs: false,
   spyOn: false,
   spyOnEvent: false,
   waitsFor: false,
   xdescribe: false
};
  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Mark Rushakoff

You can’t (yet) programmatically copy an image to the clipboard from a Javascript web app

Mark Rushakoff
Sunday, July 29, 2012

Earlier this week we had an investigation chore about whether it was possible to programmatically copy an image to the clipboard in a Javascript web app.

Our conclusion was no, it’s not currently possible (at least not standardized across browsers).

While there is a draft for the HTML5 clipboard API that does look like it will support copying images to the clipboard, it isn’t yet standardized.

After the jump, I’ll explain the steps we took to reach our conclusion.

When we started investigating, we were searching for something like “javascript copy image to clipboard” and we were not finding any relevant search results.

We decided to look up how to copy text, then. A cursory web search for copying text to the clipboard in Javascript will show you a lot of people recommending Flash-based solutions like Zeroclipboard. Zeroclipboard works by using a flash movie that copies text to the clipboard when clicked.

A search through Zeroclipboard’s documentation didn’t turn up anything about images. Thankfully, Zeroclipboard is open source! Let’s find how they are doing the copy.

We went to the Actionscript (Flash’s ECMAScript-based programming language) source code for Zeroclipboard, and found this code:

// user click copies text to clipboard
// as of flash player 10, this MUST happen from an in-movie flash click event
System.setClipboard( clipText );

System.setClipboard it is. Maybe there’s a richer API than just copying text? Off to the docs!

The Actionscript docs had this to say about System.setClipboard:

This method is provided for SWF content running in Flash Player 9. It allows only adding String content to the Clipboard.

Flash Player 10 content and content in the application security sandbox in an AIR application can call the Clipboard.setData() method.

So Flash Player 10 can do something besides strings? Let’s look at the docs for Clipboard.setData.

The standard formats are:

  • BITMAP_FORMAT: a BitmapData object (AIR only)
  • FILE_LIST_FORMAT: an array of File objects (AIR only)
  • HTML_FORMAT: HTML-formatted string data
  • TEXT_FORMAT: string data
  • RICH_TEXT_FORMAT: a ByteArray containing Rich Text Format data
  • URL_FORMAT: a URL string (AIR only)

There you have it. If we were writing an AIR app, we could use Flash to copy an image to the clipboard; but a Flash movie embedded in a web page does not have those permissions available.

So until that draft is standardized and adopted, there seems to be no cross-browser way to programmatically copy an image to the clipboard in a web app.

  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Onsi Fakhouri

Cocktail: DRY up your backbone code with mixins

Onsi Fakhouri
Tuesday, July 24, 2012

I’ve continued to enjoy using Backbone.js to build single page apps. As I’ve seen more and more real world backbone I’ve started to develop opinions to augment the blissfully unopinionated little framework that could.

One of these opinions has turned into a mini-library: Cocktail adds functionality to Backbone’s extend to facilitate breaking up reusable code into mixins. It’s pretty straightforward:

  1. Define your mixin. Mixins are just plain vanilla JavaScript objects with methods and properties hanging off of them. Here’s a slightly contrived mixin that makes a view selectable:

    window.MyMixins = {};
    MyMixins.SelectMixin = {
      initialize: function() {
        this.model.on('change:selected', this.refreshSelect, this);
      },
    
    
      events: {
        click: 'toggleSelect'
      },
    
    
      render: function() {
        this.refreshSelect();
      },
    
    
      refreshSelect: function() {
        this.$el.toggleClass('selected', this.model.get('selected'));
      },
    
    
      toggleSelect: function() {
        this.model.set('selected', !this.model.get('selected'));
      }
    }
    
  2. Mix your mixin into your views. It’s a one-liner:

    var MyView = Backbone.View.extend({
      mixins: [MyMixins.SelectMixin, MyMixins.SomeOtherMixin],
    
    
      events: {
        'click .myChild': 'myCustomHandler'
      }
    
    
      initialize: function() { ... },
      render: function() { ... },
      etc...
    });
    
  3. That’s it! Instances of MyView will automatically inherit the behaviors and methods defined in SelectMixin.

Cocktail brings two simple things to the table:

  • it adds the special mixins:[...] notation to Backbone’s extend.
  • it automatically detects and handles method collisions. In the example above Cocktail will wrap MyView‘s and SelectMixin‘s implementations of initialize into one method and assign that method to the new, composite, class. The return value of this composite method is the last non-undefined value returned by the methods it wraps. All colliding methods are handled this way, as is the events hash (the events hashes all get merged together).

There are more details and examples at the repo. In particular, there’s an example for testing mixins with Jasmine — it goes over a pattern for writing shared behaviors in Jasmine.

  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Mark Rushakoff

JavaScript disappoints yet again: sorting an array of numbers

Mark Rushakoff
Tuesday, July 3, 2012

We were writing a spec yesterday where we had a method that was returning an array of numbers in no particular order, and we wanted to verify its output. It went something like:

expect(model.foo().sort()).toEqual([1, 2, 3, 10, 25]);

The error message from Jasmine was something like “expected [1, 10, 2, 25, 3] to equal [1, 2, 3, 10, 25]“.

I couldn’t believe it. I wanted to sort an array of numbers, and JavaScript decided it would do me a favor and cast them all to strings first.

The workaround is simple: Mozilla recommends just passing a comparison function to sort:

expect(model.foo().sort(function(a, b) {
    return a-b;
})).toEqual([1, 2, 3, 10, 25]);

When you’re working in JavaScript everyday, you learn to expect the unexpected to some extent, but even this one threw me off.

  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Mark Rushakoff

Simplifying View-View Events in Backbone using the Mediator Pattern

Mark Rushakoff
Thursday, June 14, 2012

In most single-page apps, you will inevitably end up having multiple views on one page at a time.
It usually starts out with just one view, and then that view needs to bind to events on a subview, and then the subview gets its own subview who will also trigger events that affect the top-level view…

When you have one view that ties to one model, the standard way to set up the binding in Backbone looks something like

MyView = Backbone.View.extend({
  initialize: function() {
    this.model.bind("change:someProp", this.render, this);
  }
  // ...
});

You might later find yourself binding view events in the same way:

MySubView = Backbone.View.extend({
  events: {
    "click li.foo": "fooSelected"
  },

  fooSelected: function(e) {
    this.trigger("foo:selected", new Foo({id: $(e.target).data("fooId") }));
  }
  // ...
});

MyView = Backbone.View.extend({
  initialize: function() {
    this.model.bind("change:someProp", this.render, this);
    this.subview = new MySubView();
    this.subview.bind("foo:selected", this.addFoo, this);
  },

  addFoo: function(foo) {
    var fooView = new FooView({model: foo});
    fooView.bind("someOtherEvent", this.render, this);
    this.$(".foos").append(fooView.render().$el);
  }
  // ...
});

This can get out of hand rather quickly in several ways:

  • You have to add a lot of code to your view to just to wire up the events properly, and your view has to be very aware of specific subviews
  • If you have three or more levels of views, then the views in the middle may need to “forward” events between subviews and parent views
  • You can end up binding the same method to the same event on subviews of the same class
  • To test that the events are configured correctly, you will need to instantiate all of the necessary subviews in your tests

In my experience, one of the cleanest solutions to this problem is to apply the mediator pattern.

(To be fair: it would be better if we could avoid needing a mediator altogether, but that is often not a realistic goal.)

The Mediator Pattern

Concept

The mediator is a centralized object (often a singleton) whose public API looks roughly like:

  • subscribe(string channel, function callback)
  • publish(string channel, arguments)
  • unsubscribe(string channel, function callback)

Even though your views are still coupled together through their layout hierarchy, your event logic is coupled completely around the mediator.
The good news is that your view events just became enormously easier to test.

Testing

The naive way to test view events before introducing a mediator may look something like this, in Jasmine:

describe("the subview", function() {
  describe("the foo:selected event", function() {
    var spy;
    beforeEach(function() {
      spy = jasmine.createSpy();
      subview.bind("foo:selected", spy);
    });

    it("is triggered when clicking on a li.foo", function() {
      subview.$("li.foo:eq(0)").click();
      expect(spy).toHaveBeenCalled();
    });
  });
});

describe("the view", function() {
  describe("the foo:selected event", function() {
    beforeEach(function() {
      spyOn(view, "fooSelected");
      view.subview.configure();
      view.render();
    });

    it("calls fooSelected", function() {
      view.subview.trigger("foo:selected");
      expect(view.fooSelected).toHaveBeenCalled();
    });
  });
});

It looks fairly simple when written this way, but in the real world, getting your views all set up and rendered may be significantly more complicated.

After introducing a mediator, you only need to test the interaction between your view and the mediator.
If you write some custom matchers, your tests can look as clean as this:

describe("the subview", function() {
  describe("the foo:selected event", function() {
    it("is triggered when clicking on a li.foo", function() {
      expect(function() {
        subview.$("li.foo:eq(0)").click();
      }).toPublish("foo:selected");
    });
  });
});

describe("the view", function() {
  describe("the foo:selected event", function() {
    it("calls fooSelected", function() {
      spyOn(view, "fooSelected");
      Mediator.publish("foo:selected");
      expect(view.fooSelected).toHaveBeenCalled();
    });
  });
});

Existing libraries

There are a decent number of libraries out there that do mediation and only mediation.
Surveying some of the libraries listed on microjs turns up several:

  • Mediator.js
  • smokesignals
  • Radio.js
  • callbacks.js
  • MinPubSub
  • js-signals

A quick Google search will turn up even more libraries:

  • Postman

But we’re already using Backbone…

Exactly!
You don’t need any external libraries because Backbone already provides everything you need to implement the mediator pattern.
Backbone.Events is what provides the existing bind/unbind/trigger functionality, which is everything you need to make your own mediator.
In fact, they even briefly mention this concept in the Backbone docs:

For example, to make a handy event dispatcher that can coordinate events among different areas of your application: var dispatcher = _.clone(Backbone.Events).

If you do choose to use the mediator pattern, here are some other extensions to that basic pattern that may be helpful:

  • Consider what you want your mediator to do when the same function is bound twice to the same event name.
    In some cases this is correct and it should call that function twice, but in other situations that is a programming error.
    Consider also when the function is the same but the context differs.
  • Sometimes a bindOnce function is handy – unsubscribe immediately after invoking the callback.
  • Make sure that both in the app (”between” pages) and in your tests (between specs) you unsubscribe all existing subscriptions so that you don’t leak references to objects that you are no longer using.
  • Depending on how you implement your mediator, you’ll probably want to write a custom matcher for your test library as well.
  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Onsi Fakhouri

Coccyx: plug up those backbone leaks

Onsi Fakhouri
Wednesday, June 13, 2012

A number of projects at Pivotal have been using Backbone.js to build single page web apps. I’ve enjoyed using Backbone: it’s lightweight, unopinionated, helps encourage good separation of concerns between models and views, and reduces a fair bit of JavaScript boilerplate by bringing just enough framework to the table.

Unfortunately, it’s very easy to write Backbone code that leaks – especially in the view layer. A common backbone pattern is to set up some event bindings for a view:

var MyView = Backbone.View.extend({
    initialize: function() {
        this.model.on('change', this.update, this);
        this.someOtherModel.on('change', this.update, this);
        this.boundResizeHandler = _.bind(this.resizeHandler, this);
        $(window).on('resize', this.boundResizeHandler);
    },
    ...etc..
});

If your app needs to switch between several such views it is not enough to simply remove the view’s DOM and null out any references to the view. You must also unbind these event bindings in order for the view to be garbage collected. Moreover, if this view contains any subviews, you must also tear down all event bindings for all its subviews. If you do not succesfully clear out all bindings the view (and/or its subviews) will leak.

What’s worse: while there are some great tools out there to identify leaking objects, Backbone’s default constructor lists all objects as type child. This makes finding the leaky Backbone objects that are instances of MyView nearly impossible in Chrome’s heap propfiler.

Coccyx attempts to adress these problems by doing two things:

  1. Coccyx adds named constructors to Backbone. You no longer need to wonder which child is yours. By adding constructorName when you extend a Backbone class you’ll be able to easily tell which object is which in the console and the heap profiler.

  2. Coccyx implements teardown-able view hierarchies. You can easily build view hierarchies in which parents are aware of their children and can tear the entire structure down by calling tearDown() on a root node. tearDown() automatically unbinds any Backbone event bindings, cleans up DOM events and gives your view a chance to perform any custom teardown via a callback.

There are many more details at https://github.com/onsi/coccyx. Bug reports and pull requests are encouraged!

  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Tyler Schultz

[Standup][SF] 2012.05.25 – 1 git repo, 2 Procfiles, 2 Heroku Apps, CSS transitions behaving badly

Tyler Schultz
Friday, May 25, 2012

Ask for Help

*”1 git repo, 2 Heroku apps, 2 procfiles? Heroku currently is limited to 1 procfile per repo, so we’ve created a rake task that branches, modifies the procfile and pushes. Do you have a better solution?”

Is it possible to use env variables to parameterize your Procfile?

“Capybara: How can I click on a flash dialog for webcam settings?”

This was solved by right clicking and going into flash settings and enabling this permission always for this domain. Setting this up on headless CI may be more difficult.

“I have CSS transitions that behave differently when ‘user initiated’ vs initiated from a setTimeout or other event.”

  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Mark Rushakoff

Chrome and Firefox throttle setTimeout/setInterval in inactive tabs

Mark Rushakoff
Wednesday, February 29, 2012

Do your Jasmine tests (or anything else) seem to lock up when they aren’t the active tab in your browser?

Unfortunately, your new and modern browser is to blame. There are a few workarounds, but none of them are ideal in my opinion.

The cause of the problem

In early 2011, both Firefox and Chrome clamped the minimum wait time for setTimeout and setInterval to one second when running in a tab that is not the active tab for its window.

You might also be surprised to find out that HTML5 specifies a minimum of 4ms delay for setTimeout.

Workarounds

Workaround 1: Run that tab in its own window

This is the easiest solution, but it’s often less convenient to switch between browser windows when you want to just switch between tabs in the same window.

Workaround 2: Compensate for the fact that your callbacks will happen at most once per second

The accepted answer at this StackOverflow question demonstrates how you can figure out “where your animation is supposed to be” and just jump ahead. This workaround probably doesn’t apply if you have logic beyond visuals that depend on somewhat accurate timing.

Workaround 3: Use another, newer (and not necessarily standardized) API

window.postMessage

Mozilla suggests that you use window.postMessage to achieve sub-4ms delays.

window.setImmediate

Microsoft recommends using the setImmediate function as a replacement for setTimeout with a delay of 0.

But Mozilla has this to say about setImmediate:

This method is currently only proposed, is not expected to become standard, and is only implemented by recent builds of Internet Explorer.

On a side note, the Microsoft page has a lovely visualization of quicksort.

window.requestAnimationFrame

Another not-yet-standardized function, requestAnimationFrame seems best suited for animations, not for precise timing.

Workaround 4: Build your browser from modified source

I’m being somewhat facetious here, but Chrome and Firefox both have hardcoded constants for the interval limit. Without looking through the rest of the source code, I can’t conclusively say for either browser that there is no simple way to add support for overriding the inactive tab’s clamp value.

I saw one or two mentions about Firefox having an option to overwrite the minimum timeout limit, but since I’m not able to find those links again or any further information about those options, I’m led to believe that Firefox also does not let you override that one second minimum limit.

  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Max Brunsfeld

A convenient ‘super’ method for Backbone.js

Max Brunsfeld
Monday, January 30, 2012

Inheritance in Backbone

Backbone.js comes with a minimalist OO inheritance framework similar to the one employed by CoffeeScript. Each base class has a static method called extend that is used to create a subclass, like this:

User = Backbone.Model.extend({
  // instance methods
},
{
  // class methods
});

extend returns a constructor whose prototype inherits from Backbone.Model.prototype. References to all of Backbone.Model’s static methods and properties (including extend) are copied to the new constructor.

Calling ‘super’

The constructor also receives a __super__ property, which references its superclass.

User.__super__ === Backbone.Model.prototype

This makes it possible to call super inside of a class or and instance method:

User.prototype.save = function(attrs) {
    this.beforeSave(attrs);
    User.__super__.save.apply(this, arguments);
};

CoffeeScript has a super keyword that compiles to the line above, but when using Backbone with plain javascript, its a little grating to have to type that out.

A small layer of convenience

I wrote this little super method (test-driven using jasmine) which saves me having to repeat the constructor’s name all over the place. You call it like this:

User.prototype.save = function(attrs) {
    this.beforeSave(attrs);
    this._super("save", arguments);
};

The second parameter to _super is the array of arguments to pass to the overridden method. This is to optimize for the common case of passing the arguments object straight through.

There’s no way to avoid having to repeat the method name like that, unless you wrap every method definition with a helper function that either passes the overridden method as a parameter (a la Prototype.js) or reassigns a hidden super property behind the scenes (like JS.Class or John Resig’s approach). These approaches won’t work with Backbone’s ultra-minimalist inheritance system.

  • 0 Shares
  • Share on Facebook
  • Share on Twitter

Topics

  • agile (781)
  • rails (113)
  • testing (88)
  • ruby (83)
  • ruby on rails (70)
  • jobs (62)
  • javascript (55)
  • techtalk (44)
  • rspec (38)
  • ironblogger (32)
  • productivity (30)
  • activerecord (29)
  • gogaruco (29)
  • git (28)
  • nyc (27)
  • rubymine (26)
  • bloggerdome (23)
  • mobile (22)
  • process (21)
  • pivotal tracker (21)
  • cucumber (20)
  • design (19)
  • jasmine (19)
  • ios (18)
  • webos (17)
  • objective-c (17)
  • android (16)
  • tracker ecosystem (16)
  • palm (16)
  • "soft" ware (16)
  • fun (15)
  • ci (15)
  • cedar (15)
  • rails3 (14)
  • performance (14)
  • bdd (14)
  • gem (13)
  • css (13)
  • tdd (13)
  • selenium (12)
  • goruco (12)
  • bundler (12)
  • meetup (11)
  • railsconf (11)
  • nyc-standup (11)
  • capybara (10)
  • mac (10)
  • mojo (10)
  • chef (10)
  • api (10)
Subscribe to javascript Feed
  1. ←
  2. 1
  3. 2
  4. 3
  5. 4
  6. 5
  7. 6
  8. →
  • About
  • Case Studies
  • Team
  • Community
  • Careers
  • Contact
  • Labs
  • Events

Contact Us

contact@pivotallabs.com
+1 415-77-PIVOT
TwitterLinkedInFacebook

Pivotal Tracker

Tracker is the award-winning agile project management tool that enables real-time collaboration around a shared, prioritized backlog.
Visit pivotaltracker.com >