Quitting a Web Agency

Posted October 30th, 2012 with 3 Comments

I’m quitting from the web agency for a new adventure.

Working here was pretty much different from a startup where – usually – the founders/investors/employees are also the early adopters of the product they’re developing.

Most of the projects developed in this business suffer a very vicious flaw: who pays the project is not who is going to use the tool/app/website he paid for.
This is sad, since the main goal of the project suddendly become praising the ego maniac manager of BigWealthyCompanyThatSpendsLotsOfMoneyInMarketing and not developing something that the users will really love.
And because of that, it’s inevitable that project will fail the reality check once completed.

How can you tell if your project is failing the reality check?

  1. You don’t have server load problems
  2. The mockup of your app is something like this





    Instead of this


JsDuck tag for Deferred methods

Posted October 12th, 2012 with No Comments

I started working with the awesome JSDuck to document my projects (do you like the doc system on Sencha Touch?) and, since I’m a great fan of Deferred object, I saw the lack of support for this kind of pattern.
Setting the @return tag with something like @return {jQuery.Deferred} is not enough since the returned value that matters is that passed through the .resolve() method of the deferred object.

Would be nice to mark a method as “deferred” and use the @return tag to document the value passed with .resolve(), keeping in mind that the actual value returned by the function is a just e promise.

Luckly JsDuck supports custom tags:

require "jsduck/meta_tag"
module JsDuck::Tag
  # Implementation of @deferred tag
    class Deferred < JsDuck::MetaTag
    def initialize
      @name = "deferred"
      @key = :deferred
      @signature = {:long => "deferred", :short => "DEF"}
      @boolean = true
    end
  end
end

Put this somewhere, for example ‘jsduck/deferred.rb’ and remember to call JsDuck with the param “–meta-tags=jsduck/deferred.rb”.

Deferred object as callback

Posted October 10th, 2012 with 6 Comments

Callbacks are a nice way of Iversion of control, but are even more powerful with deferred objects.
Basically callbacks are a way to pass back the control from a called function, the deferred/promise just do the opposite: it returns the control the called function.

Consider this scenario: a table widget, with the classic delete/modify buttons next to each row. Since the table widget is a generic component, we want to handle the delete operation on the model outside the widget, and we don’t event want to extend the generic object to do that, we want to user a callback:

$.widget('my_table_widget',{
  onDelete: function(id_of_row) {
    var that = $(this);
    // call the backend and delete the record
    $.ajax({
      method: 'delete',
      url: '/api/records/'+id_of_row
      })
      .done(function() {
        // ok, record delete, now I should update the table
        that.widget('remove_row',id_of_row);
        });
      }
    });

In the example above: the callback first calls the backend to remove the record and then removes the row from the table (I mean the DOM). In order to do this: it needs to know something about the table widget (in this case, the method “remove_row”).
But what if we could pass the ball back to the widget? Let’s rewrite it with a deferred object:

$.widget('my_table_widget',{
  onDelete: function(id_of_row) {
    var deferred = $.Deferred();
    // call the backend and delete the record
    if (confirm('Delete?')) {
      $.ajax({
        method: 'delete',
        url: '/api/records/'+id_of_row
        })
        .done(function() {
          // ok, record delete, now I should update the table
          deferred.resolve();
          })
        .fail(function() {
          deferred.reject();
          })
      }
    else {
      deferred.reject();
      }
    return deferred.promise();
    }
  });

It’s more linear but, most important, the callback knows nothing about the remove_that_damn_row_from_the_dom method of the widget, it just passed back the control, it’s like saying “I’m done, it’s your turn”.
More separation, less documentation to read, easier to implement, less errors.

On the widget side, the callback should be treated this way

// somewhere inside the table widget, here is where we execute the callback
var callback_result = options.onDelete.call(widget,id);
// if the callback answer with a deferred/promise, this will
// handle it when it's resolved/rejected
if (isPromise(callback_result)) {
  callback_result
    .done(function() {
      // ok, asynch operation on the other side is over
      // remove the row from the dome
      widget.widget('remove_row',id);
      })
    .fail(function() {
      // do nothing
      })
  }
  • Categories

  • Tags

  • Enter your email address to subscribe to this blog and receive notifications of new posts by email.

    Join 2 other subscribers

  • Follow me on Twitter