The Software Simpleton

Nomadic cattle rustler and inventor of the electric lasso

Clojurescript - Handling Mouse Events With core.async

I came across a situation recently where I needed to know the x and y co-ordinates of the mouse while the user was dragging over a canvas element. The mousemove event will give me the x and y co-ordinates via the offfsetX and offsetY properties of the event object but I only want to record these values when the user is dragging, i.e. when the mouse is down and the mousedown event has been triggered and we are receiving mousemove events. When the user stops dragging and the mouseup event is fired, I want to stop recording the co-ordinates.

The solution was to use the illusory synchronous appearance of core.async. In my opinion, the key to having user friendly asynchronous code is to have it read as synchronous as possible and I think that core.async outshines promises, generators and any other abstraction that I have encountered to read synchronously.

I am using the excellent om library to render the html and below I am declaring 3 channels in the IInitState lifecycle event that will be stored in the local state and can be retrieved in subsequent lifecycle events.

init.cljs
1
2
3
4
5
om/IInitState
(init-state [_]
  {:mouse-down (chan)
   :mouse-up (chan)
   :mouse-move (chan 1 (map (fn [e] (clj->js {:x (.-offsetX e) :y (.-offsetY e)}))))})

I am creating 3 channels to handle the mousedown, mouseup and mousemove events and storing them in the local state.

On line 4 I am creating a channel and also supplying a transducer to the channel that will transform each event object that is placed on the channel.

In the IDidMount lifecycle event that is triggered when the component is mounted onto the dom and is displayed below, I am retrieving the channels from the local state and creating event listeners for the mouse events that I am interested in, MOUSEDOWN, MOUSEUP and MOUSEMOVE. All these event handlers do is basically put! the event object onto the relevant channel:

didmount.cljs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
om/IDidMount
(did-mount [_]
  (let [canvas (q ".tutorial")
        ctx (.getContext canvas "2d")
        mouse-down (om/get-state owner :mouse-down)
        mouse-up (om/get-state owner :mouse-up)
        mouse-move (om/get-state owner :mouse-move)]

    ; we use put! because we are not in a go block
    (listen canvas EventType.MOUSEDOWN #(put! mouse-down %))
    (listen canvas EventType.MOUSEMOVE #(put! mouse-move %))
    (listen canvas EventType.MOUSEUP #(put! mouse-up %))

    (set! (.-lineWidth ctx) 3)))

Now we come to the meat and two potatoes of the piece. Below is the IWillMount handler that is called before the component is mounted onto the dom:

willmount.cljs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
om/IWillMount
(will-mount [_]
  (let [mouse-down (om/get-state owner :mouse-down)
        mouse-up (om/get-state owner :mouse-up)
        mouse-move (om/get-state owner :mouse-move)]

    (go-loop []
      (loop []
        (alt! [mouse-down] ([down]
                              (do (log "we hit mouse down and onto next loop.") nil))))
      (log "we won't reach here until mouse down.")
      (loop []
        (alt! [mouse-up] ([up] (do (log "we hit mouse up, final recur and back to previous loop.")  nil))
              [mouse-move] ([coords]
                              (do
                                (log coords)
                                (recur)))))
      (recur))))

As before, in lines 3-5 I retrieve the channels from local state.

On line 7 a go-loop is created. A go-loop is a convenience or shorthand for (go (loop ...)). The go-loop appears to create an infinite loop but actually it creates a statemachine that turns synchronous/blocking looking code into asynchronous non-blocking code. If there are no events then the go block is suspended. The go macro will expand out calls to <!, >!, alts! or in our case alt! into an asynchronous non-blocking statemachine.

On line 8 of the above, we use a combination of loop and alt! to suspend execution until a mousedown event is triggered. Execution will not reach the second inner loop on line 12 until the alt! expression on line 9 receives the mousedown event and returns nil on line 10.

alt! works like a sort of poor man’s pattern matching by dispatching execution to the right hand side s-expression of the left hand side channel that has received the event.

When the mousedown event is triggered, execution then proceeds to line 12 in a nice synchronous manner where a second loop will listen for mouseup or mousemove events via the alt! expression on line 13.

If mousemove events are received then we are simply logging the transformed event object that is transformed via the transducer that was passed to the channel initialisation in IInitState:

trans.cljs
1
:mouse-move (chan 1 (map (fn [e] (clj->js {:x (.-offsetX e) :y (.-offsetY e)}))))

While the stream of mousemove events are received on the mouse-move channel on line 14, the recur statement on line 17 will keep execution on this inner loop.

When the user stops dragging and the mouseup event is fired and received on the mouse-up channel on line 13. nil is returned which breaks execution out of this inner loop and execution continues onto the recur on line 18 which belongs to the go-loop and execution goes back to the first inner loop on line 8 where the code appears to block as it listens for the next mousedown event.

I found this a very interesting approach and the code appears beautifully synchronous which of course it is not. I also like the ability to supply a transducer to the core.async channel to transform the incoming input. This decouples things nicely.

Clojurescript - Using Transducers to Transform Native Javascript Arrays

I’ve been digging into clojurescript more and more but as I am still quite new to cljs, I find myself over zealously calling the clj->js and js->clj interop functions that transform javascript arrays to clojurescript vectors, maps, lists etc. and vice versa. I found this frustrating as I want to use the power of the clojurescript language and not have to drill down to javascript unless it absolutely necessary.

I’ve been writing a react wrapper component which has pretty much dictated that I need to be dealing with native javascript objects at all times and as such I am having to call these interop functions. An example of this is in the code below:

keys.cljs
1
2
3
4
5
6
7
(let [prevKeys (.keys js/Object (or prevChildMapping (js-obj)))
      nextKeys (.keys js/Object (or nextChildMapping (js-obj)))
      keysToEnter (clj->js (filter #(not (.hasOwnProperty prevChildMapping %)) nextKeys))
      keysToLeave (clj->js (filter #(not (.hasOwnProperty nextChildMapping %)) prevKeys))]

      (set! (.-keysToEnter this) keysToEnter)
      (set! (.-keysToLeave this) keysToLeave)))))

On lines 3 and 4, I am calling clj->js to transform a clojurescript PersistentVector into the javascript native array equivalent. What I really wanted was to call the clojurescript sequence functions map, reduce, filter etc. on native javascript objects. I asked if this was possible in the clojurescript irc and transducrs were put forward as a means of achieving the goal.

Transducers

I had heard of transducers in the clojure world without taking the trouble to see what all the fuss was about but I had no idea that they were available in clojurescript. I’m now going to give a brief introduction as to what transducers are but there is lots of good material out there that probably do a better job and Rich Hickey’s strangeloop introduction to them is a great start.

I always address a new concept by first of all determining what problem does the new concept solve and with tranducers the problem is one of decoupling. You are probably familiar with filter which returns all items in a collection that are true in terms of a predicate function:

filter.cljs
1
(filter odd? (range 0 10)) ;=> (1 3 5 7 9)

It should be noted that filter could be constructed using reduce.

filter-odd.cljs
1
2
3
4
5
6
7
(defn filter-odd
  [result input]
  (if (odd? input)
    (conj result input)
    result))

(reduce filter-odd [] (range 0 10))

The problem with the above is that we cannot replace conj on line 4 with another builder function like+. This problem holds true for all the pre-transducer sequence functions like map, filter etc. Transducers set out to abstract away operations like conj so that the creation of the resultant datastructure is decoupled from the map/filter logic.

conj and + are reducing functions in that they take a result and an input and return a new result. We could refactor our filter-odd function to a more generic filtering function that allows us to supply different predicates and reducing funtions by using higher order functions:

filtering.cljs
1
2
3
4
5
6
7
8
9
10
(defn filtering
  [predicate]
  (fn [reducing]
    (fn [result input]
      (if (predicate input)
        (reducing result input)
        result))))

(reduce ((filtering odd?) conj) [] (range 0 10)) ;=>[1 3 5 7 9]
(reduce ((filtering even?) +) 0 (range 0 10)) ; => 20

The above is not as scary as it looks and you can see on lines 9 and 10 that we are able to supply different reducing functions (conj and +). This is the problem that transducers set out to solve, the reducing function is now abstracted away so that the creation of the datastructure is decoupled from the sequence function (filter, map etc.) logic.

As of clojure 1.7.0 most of the core sequence functions (map, filter etc.) are gaining a new 1 argument arity that will return a transducer that, for example this call will return a transducer from filter:

odd.cljs
1
(filter odd?)

One of the new ways (but not the only way) to apply transducers is with the transduce function. The transduce function takes the following form:

transduce.cljs
1
transduce(xform, f, init, coll)

The above states that transduce will reduce a collection coll with the inital value init, applying a transformation xform to each value and applying the reducing function f.

We can now apply this to our previous example

xform.cljs
1
2
3
4
5
(def xform
  (filter odd?))

(transduce xform + 0 (range 0 10)) ;=> 25
(transduce xform conj [] (range 0 10)) ;=>  ;=>[1 3 5 7 9]

I hope it is obvious that (range 0 10) is coll and [] is the init, xform is the transducer function and + or conj are the reducing functions.

Meanwhile Back in Javascript land……

If we now shift back to our specific example, we can use a transducer to transform a native javascript array because a transducer is fully decoupled from input and output sources.

This is the current code that we want to refactor:

cljs.cljs
1
(clj->js (filter #(not (.hasOwnProperty prevChildMapping %)) nextKeys))

So the first question is what would the reducing function be when dealing with native arrays? The answer is the native array push push method which adds a new item to an array. My first ill thought out attempt at the above looked something like this:

transduce.cljs
1
(transduce (filter #(not (.hasOwnProperty prevChildMapping %))) (.-push #js[]) #js [] nextKeys)

This is completely wrong because I had not grasped what is required of the reducing funcion. A reducing function takes a result and an input and returns a new result e.g.

conj.cljs
1
2
(conj [1 2 3] 4) ;=> [1 2 3 4]
(+ 10 1) ;=> 11

The push function does not satisfy what is required as the push function actually returns the length of the array which is not what is expected. What was needed was someway of turning the push function into a function that behaved in a way that the transducer expected. The push function would need to return the result:

arr.cljs
1
(fn [arr x] (.push arr x) arr)

But as it turns out, this also does not work because a reducing function to transduce has to have 0, 1 and 2 arities and our reducing function only has 1.

As it turns out, both clojure and clojurescript provide a function called completing that takes a function and returns a function that is suitable for transducing by wrapping the reducing funtion and adding an extra arity that simply calls the identity function behind the scenes. Below is the completing function from the clojure.core source.

completing.cljs
1
2
3
4
5
6
7
(defn completing
  ([f] (completing f identity))
  ([f cf]
     (fn
       ([] (f))
       ([x] (cf x))
       ([x y] (f x y)))))

My final code ended up looking like this:

keys.cljs
1
(keysToEnter (transduce (filter #(not (.hasOwnProperty prevChildMapping %))) (completing (fn [arr x] (.push arr x) arr)) #js [] nextKeys)

The reducing function that uses the native javascript push function is wrapped in completing that makes it suitable for transducing.

I think I’ve ended up with more code than I started with and I also think that this is a poor example of transducers but I wanted to outline the mechanics involved in using transducers with native javascript arrays as I could find absolutely nothing on the google etc. so hopefully this will point somebody else in the right direction.

If I have got anyting wrong in this explanation then please leave a comment below.

Clojure - Installing a Local Jar With Leiningen

I ran into a situation earlier where I wanted to use the 0.8.0-beta2 version of om but it had not yet been pushed to clojars.

The answer was to install the jar in a directory local to the project I was working on.

Here are the steps I took to install the om jar locally:

Ember.js - Programmatically Bind From a Handlebars Helper

Warning: The examples use Ember 1.7.1

This is a quick update to my last post where I created a helper that bound data from an external json hash.

One problem I ran into was that if I was not creating links via the link-to helper then the properties were not bound. In line 11 of the gist below, I am returning a simple string that will render the unbound property wrapped in a span tag.

bad.js
1
2
3
4
5
6
7
8
9
10
11
12
Ember.Handlebars.registerBoundHelper('getProperty', function(context, property, options) {
  var defaults, prop;
  defaults = {
    className: "",
    context: "this",
    avatar: false
  };
  property = Ember.merge(defaults, property);
  prop = context.get(property.binding);
  if (!property.hasOwnProperty("route")) {
    return new Handlebars.SafeString("<span>" + prop + "</span>");
  }

The solution was to call out to the handlebars bind helper after updating the options hash on lines 2-5 below:

good.js
1
2
3
4
5
  if (!property.hasOwnProperty("route")) {
    options.contexts = [context];
    options.types = ["ID"];
    return Ember.Handlebars.helpers.bind.call(context, property.binding, options);
  }

Here is an updated jsbin with a full working example.

I am not sure if this is relevant for life after ember 1.7.1 but these techniques have worked well for me thus far.

Ember.js - Rendering Dynamic Content

Warning: The examples use Ember 1.7.1

I’m not going to go into great detail in this post as I think the code examples will be out of date post ember 1.7.1.

I recently had the problem of how to make a complex table reusable accross different datasets. As each dataset would contain objects with different fields, I would not be able to use the usual handlebars syntax of binding:

1
{{property}}

My solution was to create a json hash that is similar to the one in the gist below that specified which fields I was binding to and whether or not, I was going to render a simple text field, a link or for complex scenarios a component:

hash.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
App.IndexController = Ember.ArrayController.extend({
  columns: Ember.A([
   {
      heading: "Heading",
      binding: "name",
      route: "company"
    },
    {
      heading: "Address",
      binding: "address"
    },
    {
      heading: 'full',
      component: 'full-contact',
      bindings: ['name', 'address']
    }
  ])
});
  • The address structure on line 9 is the most basic as it just specifies a property to bind to.
  • The structure on line 4 contains a route property to signify that I want a link generated.
  • The structure on line 13 contains a component property that unsurprisingly will render a component. A component can also take an array of bindings on line 15 that will have the effect of calling the component like below:
1
{{full-contact name=name address=address}}

Now in my template, I just iterate over this columns collection and either call a handlebars helper that renders the text or link (line 9) or I call out to a different helper that will render the component (line 7)

If I am rendering a simple text or link, then I call the helper that is outlined below:

getproperty.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
Ember.Handlebars.registerBoundHelper('getProperty', function(context, property, options) {
  var args, defaults, id, prop;

  defaults = {
    className: "",
    context: "this",
    avatar: false
  };

  property = Ember.merge(defaults, property);
  prop = context.get(property.binding);

  if (Ember.isEmpty(prop)) {
    return "";
  }

  if (!property.hasOwnProperty("route")) {
    return new Handlebars.SafeString("<span>" + prop + "</span>");
  }

  args = Array.prototype.slice.call(arguments, 2);

  options.types = ["ID", "STRING", "ID"];
  options.contexts = [context, context, context];

  id = property.context ? "" + property.context + ".id" : "id";

  args.unshift(id);
  args.unshift(property.route);
  args.unshift(property.binding);

  return Ember.Handlebars.helpers["link-to"].apply(context, args);
});

If I am rendering a component then this helper is called:

component.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Ember.Handlebars.registerHelper('renderComponent', function(contextPath, propertyPath, options) {
  var context, helper, property;

  context = Ember.Handlebars.get(this, contextPath, options);
  property = Ember.Handlebars.get(this, propertyPath, options);

  helper = Ember.Handlebars.resolveHelper(options.data.view.container, property.component);

  options.contexts = [];
  options.types = [];

  property.bindings.forEach(function(binding) {
    options.hash[binding] = binding;
    options.hashTypes[binding] = "ID";
    options.hashContexts[binding] = context;
  });

  return helper.call(context, options);
});

Here is a working jsbin.

That is all I have to say on the matter but I would love to hear an alternative or better approach to the above.

Clojurescript - Om - Dynamic Components and Unique Keys

As I get older my tolerance for javascript seems to be getting worse so I’ve been employing clojurescript as a shield from the true horrors of javascript. I’ve been playing around wih om which acts as an interface to facebook’s react.

While developing with om, I kept getting the same javascript error after rendering a dynamic list like below:

If you have done any developing with om, then I am confident in saying that you will have come across this warning after rendering such a list:

Each child in an array should have a unique “key” prop. Check the renderComponent call using <tbody>. See http://fb.me/react-warning-keys for more information.

Here is the code I was using to render such a list:

old.cljs
1
2
3
4
5
6
7
8
9
10
11
12
(defn clips-view [{:keys [clips]} owner]
  (reify
    om/IRender
    (render [this]
      (html/html
        [:div.well
         [:table.table.table-bordered.table-hover.table-striped
          [:tbody
           (if (empty? clips)
             [:tr
              [:td.text-center {:colSpan "2"} "No Clips!"]]
             (om/build-all clip-view clips))]]]))))

Line 12 in the above is the villain of this piece as there is no way that I could find of passing a func that will set the key property that react uses to identify each dynamic child.

I have been trying to ignore this warning as it did not cause any code to stop executing but I kept seeing this question pop up on the irc channel and I could not find a good answer on the google.

It also turns out that not supplying a react key for each dynamic item could lead to some very unexpected behaviour.

After consulting the om docs I discovered that om/build can take a third :opts argument and one of the allowed keys is a :react-key which is one of the solutions to the problem.

Armed with this information, I refactored the above code to the following:

refactor.cljs
1
2
3
4
5
6
7
8
9
10
11
12
(defn clips-view [{:keys [clips]} owner]
  (reify
    om/IRender
    (render [this]
      (html/html
        [:div.well
         [:table.table.table-bordered.table-hover.table-striped
          [:tbody
           (if (empty? clips)
             [:tr
              [:td.text-center {:colSpan "2"} "No Clips!"]]
             (map-indexed #(om/build clip-view %2 {:react-key %1}) clips))]]]))))

The only change is on line 12:

1
(map-indexed #(om/build clip-view %2 {:react-key %1}) clips))

I have used the simplest case of an index for the :react-key but if I was rendering from a list where each item had a unique identifier then I would use the :key option to specify an element property that would be bound as the react key and would look something like this:

b.clj
1
(map #(om/build clip-view % {:key :id}) clips))

(thanks to Anna Pawlicka) for mentioning this in the comments below.

Or probably the best option of is to pass an :opts map containing a :key option to om/build-all:

a.clj
1
(om/build-all clip-view clips {:key :id})

Thanks to Daniel Szmulewicz for mentioning this on twitter.

I can now paste a link to this post when somebody asks how to get rid of this warning on the clojurescript irc channel.

Clojure - Lazy Sequences for the Masses

I have recently fallen head over heals in love with clojure and I’ve decided to run through the problems in the excellent 4Clojure site to ensure that I have a good understanding of the language before I even think about dealing with IO or building something meaningful. I’m currently on question 60 which has introduced the concept of lazy sequences and is displayed below:

r.clj
1
2
3
4
5
Write a function which behaves like reduce, but returns each intermediate value of the
reduction.  Your function must accept either two or three arguments, and the return
sequence must be lazy.

(= (take 5 (__ + (range))) [0 1 3 6 10])

What struck me as totally strange when I first read this problem is that an infinite list is being passed to the function in the form of (range). I had only previously seen range used with at least an end argument like below:

range.clj
1
2
user=> (range 10)
(0 1 2 3 4 5 6 7 8 9)

But if no start or end arguments are supplied then the default for end is infinity.

d.clj
1
2
3
;; default value of 'end' is infinity
user=> (range)
(0 1 2 3 4 5 6 7 8 9 10 ... 12770 12771 12772 12773 ... n

So why on earth would you want to supply an ever expanding range? The answer to this puzzle within a puzzle was to clarify what range actually returns which according to the docs is:

Returns a lazy seq of nums from start (inclusive) to end (exclusive), by step, where start defaults to 0, step to 1, and end to infinity.

The 4clojure problem at the start of this post also asks the user to return a lazy sequence for the solution. So what is a lazy sequence? As a newbie to clojure, I struggled to find good information of what an actual lazy sequence was and the docs left me with an unclear understanding of how I should use lazy-seq to construct a lazy sequence.

Lazy Sequences

Laziness in this context means that you can specify a computation that could theoretically take forever to complete, but you can evalutate as much or as little of it as you need. A very simple example of this is below:

take.clj
1
2
user=> (take 10 (range))
(0 1 2 3 4 5 6 7 8 9)

In the above example, range is being called with no end argument which according to the docs will mean that end defaults to infinity but if we type the expression into the repl, a sequence with the first 10 elements is immediately evaluated so it would appear that take 10 is not waiting for range to reach infinity before grabbing the first 10 elements.

A closer look at what type of sequence is returned starts to give the game away:

class.clj
1
2
user=> (class (take 10 (range)))
clojure.lang.LazySeq

As range with no end argument defaults to infinity, the only way that this could possibly work is if range returns a lazy sequence or one that realizes its elements as requested. The original 4Clojure problem stated that the sequence returned from the solution must be lazy in order to work with an infinite range:

t.clj
1
(= (take 5 (__ + (range))) [0 1 3 6 10])

After a quick google to determine how I can return a lazy sequence, I came across the clojure docs for the lazy-seq function but I did not fully grasp what the explanation meant:

Takes a body of expressions that returns an ISeq or nil, and yields
a Seqable object that will invoke the body only the first time seq
is called, and will cache the result and return it on all subsequent
seq calls. See also - realized?

In my haste to complete the problem, I simply thought that all I had to do was wrap an existing function in a lazy-seq call and everything would just magically work. Here is my original attempt at solving the question:

first.cljs
1
2
3
4
5
(= (take 5 ((fn [func se]
    (lazy-seq
        (reduce (fn [acc item]
                      (conj acc (func (last acc) item)))
                        [(first se)] (rest se)))) +  (range))) [0 1 3 6 10])

All I have done is wrap a call to reduce on line 3 in a call to lazy-seq on line 2 which of course resulted in a stackoverflow because reduce does not return a lazy sequence and instead will execute until the computation is complete which in this case is never because reduce is being called on an infinite list. I needed to go back to the drawing board. What I needed to do was create a sequence that is realized as needed.

After a bit more digging it became apparent that lazy sequences are not really sequences that simply return a list of elements but are more comparable to iterators in other languages such as java that conform to an a sequence api. With a lazy sequence it is up to the client or the calling function to decide how many elements to consume. A lazy function is just a data structure that waits until you ask it for a value. So how does one return a lazy sequence?

The Simplest Example Imaginable

Below is the simplest example that I could think of:

simple.clj
1
2
3
4
(defn add-one [se]
  (lazy-seq (cons (inc (first se)) (add_one (rest se)))))

(take 5 (add-one (range))) ;;;;;;=>(1 2 3 4 5)
  • Line 1 defines a function named add-one that accepts a sequence that could be infinite.
  • Line 2 is where the action happens, the lazy-seq macro is employed to create a lazy sequence whose body is an expression. The body of this lazy sequence uses the cons function which takes an element and a sequence and returns a new sequence by prepending the element to the sequence. The element in this case is the result of incrementing the first element of the list with the expression:
inc.clj
1
(inc (first se))

The sequence that the element is prepended to is the result of recursively calling the add-one function again. If a lazy sequence was not returned from add-one then add-one would be called over and over again until a stackoverflow exception was thrown. The whole point of the lazy-seq macro is to circumvent this and ensure that the function will only be accessed as the elements are requested. A sequence that is returned from lazy-seq contains the requested element and a pointer or a function to get the next element.

Another mistake I made in my original misunderstanding was that cons was returning a lazy sequence or was somehow involved in returning a lazy sequence. cons does not return a lazy sequence (the thing that does that is lazy-seq), but it is a good tool to use as part of buidling a lazy sequence.

The 4clojure Solution

Before I show my solution, I will remind you of the original 4Clojure problem.

red.clj
1
2
3
4
Write a function which behaves like reduce, but returns each intermediate value of the reduction.
Your function must accept either two or three arguments, and the return sequence must be lazy.

(= (take 5 (__ + (range))) [0 1 3 6 10])

The question is really asking the user to recreate clojure’s core reductions function. Below is my solution that took me quite a while to get to but I am very pleased with.

res.clj
1
2
3
4
5
6
7
8
9
10
11
12
(= (take 5 (
  (fn my-reduct
    ([func coll]
       (my-reduct func (first coll) (rest coll)))

    ([func firstArg coll]
      (letfn [(reduct [f init se]
                (lazy-seq (when-not (empty? se)
                            (let [res (f init (first se))]
                              (cons res (reduct f res (rest se)))))))]
        (lazy-seq (cons firstArg (reduct func firstArg coll))))))
                    + (range))) [0 1 3 6 10])

The important things to note are that an infinite range is passed into the named anonymous function my-reduct on line 12 but becase a lazy sequence is returned on line 8 and line 11, the resulting sequence will only be returned as requested. Because the take function is used on line line 1 to request the lazy sequence with an arguement of 5, the function will only be called 5 times.

I found lazy sequences very difficult to wrap my head around and part of that process was to write this post.

If I have inaccuately described anything or I can improve this explanation then please leave a comment below.

ember.js - Animating Deletes With the BufferedProxy

I encountered an interesting scenario in my day job that initially had me scratching my head for a way to solve and seems worthy of a post. The real world application that I am working on actually has real world todos! The application lists the todos as is illustrated in the screenshot below and they can be completed in the time honoured fashion of clicking the checkmark or tick on the left hand side of the todos:

One of the requirements for this list is to display only the todos that have not been completed. Ember does make this ridiculously easy and we could even bind our list to the new filterBy computed property like this:

filterBy.js
1
2
3
4
5
App.TodosController = Ember.ArrayController.extend({
  active: Ember.computed.filterBy('@this', 'isCompleted', false);
});

// 

Here is a working jsbin that shows how easy this is.

The problem with the approach outlined in the jsbin is that, when the checkbox is checked and the bindings are flushed, the view that has been rendered for that particular todo gets instantly destroyed. There are currently no hooks that allow for animations in ember and this is particularly true when it comes to removing items from a bound list or indeed destroying views. This leaves you as the developer to resort to some sort of trickery. I would personally like to see an extra runloop queue or a view lifecycle event that returned a promise. Only when the promise has been resolved would the view’s destroy method be called. There was some discussion about this before ember 1.0 was released but we are heading towards ember 1.6 and I think we need to discuss this again.

My requirements for this todo list are even more convulted because I want to visually indicate that the todo has been checked and also give the user a 4 second chance to change their mind and uncheck the todo before the todo disappears from the list. As you can see from the jsbin, the moment the checkbox is checked, the todo just vanishes instantly. So, what can be done?

The BufferedProxy

The application that I am working on has been in active development for over a year and we still use version 0.14 of ember-data which was the last version of ember-data that was released before the much publicised reboot. I have made a solemn oath to my client that I would not even think of upgrading until ember-data reached 1.0 after the pain we suffered with other ember-data upgrades. One problem with this version of ember-data (I cannot speak for the latest version) is that it is terribly annoying to work with models that are left in isDirty or invalid states. I am not going to go into detail here but the state machine assertions are a source of depression for anybody that has had the experience. I have since patched up my slightly bastardised version of ember-data but what makes life easier is to actually not bind to an ember-data model and only create the model when you are absolutely sure that your model is ready to be persisted.

The BufferedProxy has been an absoute god send for my productivity with this version of ember-data. The BufferedProProxy is a mixin that I mixin into controllers that uses ember’s lesser know method_missing like feature (checkout unknownProperty and setUnknownProperty) to store changes to a controllers model in a buffer that you can either set explicity or you can cancel them completely without the model ever being changed. This is perfect for ember-data models. We can only apply the modifications if we are happy that the model is valid or that the user has not navigated away, cancelled, left the building, been set on fire, shot, kidnapped etc.

The BufferedProxy is ideal for my requirements which are:

  1. I want to delay setting isFinished on the model so that the user has a few seconds to change their mind and undo the change.
  2. I want to animate the deletion of the todo view to make it look a bit more polished than it is in the original bin where it instantly disappears.

Here is a a working jsbin of what I ended up with. There is a delay in persisting the change that gives the user an opportunity to cancel and the delete has a basic animation. If you re-check a todo, then it will not be removed or if you leave it checked, a basic animation will kick in and the todo will be removed when the animation is completed.

The first thing to notice is that I am using render instead of a component to render my todos which gives me a clean separation between controller and view which I think is better for this situation because I want to mix in the BufferedProxy into the controller and not the component even though I am pretty sure it would work with a component:

In the TodoController, I observe the isFinished property for changes in the following handler:

isFinished.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
isFinishedDidChange: (function(){
  var self = this;

  if (this.get('isFinished') && this.get('hasBufferedChanges')) {
    var notifyView = function() {
                       self.trigger('animateFinish');
                       return clearInterval(timer);
                     };

    timer = setInterval(notifyView, 2000);

    this.set('timer', timer);
  } else {
    if (this.get('timer')) {
      clearInterval(this.get('timer'));
    }

    if (this.get("hasBufferedChanges")) {
      this.send('completeFinish');
    }
  }
}).observes('isFinished')
  • On line 4 I am checking if the todo isFinished and the hasBufferedChanges property lets me know that there are changes in the BufferedProxy that are ready to be applied.
  • On line 5, I create an inline function that will be called after a delay. The delay is to give the user the opportunity to change their mind and cancel the change.
  • The inline function on line 5 will raise an event on line 6 to the TodoView that is listening for these events and will give the view the opportunity to animate the delete. The timer is cancelled on line 7.
  • On line 14 we handle the case where the user has changed their mind. We clear the timer and then persist the change if the BufferedProxy has changes.

Below is the TodoView that handles the animateFinish event that is triggered by the TodoController on line 6 of the above gist.

todoview.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
App.TodoView = Ember.View.extend({
  tagName: 'tr',
  didInsertElement: function(){
    this._super.apply(this, arguments);
    this.get('controller').on('animateFinish', this, 'onAnimateFinish');
  },
  onAnimateFinish: function(){
    var controller = this.get('controller');

    this.$().fadeOut('slow', function(){
      controller.send('completeFinish');
    });
  }
});
  • line 5 sets up the event handler for animateFinsh events that are raised by the TodoController.
  • lines 10 and 11 uses jQuery’s fadeOut for some basic animation which calls a controller action to persist the changes when the animation has finished.

All that remains is to show the completeFinish action that is called in the above gists:

completeFinish.js
1
2
3
4
5
6
7
8
9
10
App.TodoController = Ember.ObjectController.extend(Ember.Evented, BufferedProxy, {
  actions:{
    completeFinish: function(){
      this.applyBufferedChanges();

      this.get('model').save().then(function(todo){
        console.log(todo.get('description') + " is completed");
      });
    }
  },
  • On line 4 of the above gist, I apply the changes from the BufferedProxy by calling the applyBufferedChanges method which will transfer the changes from the buffer to the model.
  • On line 6, I persist the model.

I hope if nothing else that this post has highlighted the complexities of adding animations to ember and especially in the destroy phase. Animation is a must have for modern day javascript single page applications and not a nice to have. I’m not sure if this is on the ember roadmap but I think this is something that can no longer be ignored. I would like to see a run loop queue or view lifecycle event that allowed me to return a promise with the view’s destroy method only being called when that promise has resolved.

Please comment if any of the above has unsettled you.

ember.js - Computed Property for All Keys of an Object

I came across a situation today where I wanted to create a computed property which would recalculate itself every time one of the properties of an object changed. The lazy and tedious thing to do would have been to simply list them out like this:

long.js
1
2
3
previewHeaders: Ember.computed('headerInfo.firstName', 'headerInfo.surname', 'headerInfo.email', function(){
  //do stuff
})

This is tedious for a number of reasons but the main one is that I have to remember to update the dependent key list, every time the object changes.

Below is the solution I came up with:

just.js
1
2
3
4
5
6
7
8
9
10
11
12
App.computed.addAllKeysProperty = function(context, propertyName, objectPath, func) {
  var args, subject;
  subject = context.get(objectPath);

  args = Ember.keys(subject).map(function(key) {
    return "" + objectPath + "." + key;
  });

  args.push(func);

  return Ember.defineProperty(context, propertyName, Ember.computed.apply(this, args));
};

This is slightly more convoluted that I would have liked as I could not create a real property because I need the context argument to be an instance on line 3 so that I can call Ember.keys on this instance. Instead of creating an actual property, I use defineProperty on line 11 to create the property at runtime. I create the dependant key list by using Ember.keys to iterate over the subject’s properties and then call Ember.computed.apply to equal the call from the gist at the top of the post.

Below is the calling code:

init.js
1
2
3
4
5
6
init: function() {
  this._super.apply(this, arguments);
  return App.computed.addAllKeysProperty(this, 'previewHeaders', 'headerInfo', function() {
    //do stuff
  });
},

It is slightly dissatisfying in that I could not create an actual property and if you can suggest a better way then please leave a comment below.

Partial Functions With Bind

I gave a talk last night at the local Glasgow JavaScript user’s group and I was a little surprised that not everybody had heard of the bind method which is a member of the Function.prototype. I put the blame for this firmly at internet explorer’s door because most of us still have to deal with intenet explorer 8 and below which runs ECSMAScript 3 and bind is only available from ECSMAScript 5 and beyond. Internet Explorer has a nuclear half life that is much longer than Chernobyl and will probably still be emitting deadly radiation for many years to come.

The bind method is one solution to having to declare a self or a that or a _this variable when we want to specify what this will be when a function is executed. Below is an example where two new functions (lines 12 and 16) are created in order to set what the context will be when the two variations of the sayHello methods are executed for a particular person:

oldschool.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
var Person = function(name) {
  this.name = name;
};

var sayHello = function() {
  console.log("Hello, my name is " + this.name);
};

var bob = new Person('Bob');
var paul = new Person('Paul');

var sayHelloBob = function() {
  console.log("Hello, my name is " + bob.name);
};

var sayHelloPaul = function() {
  console.log("Hello, my name is " + paul.name);
};

sayHelloBob();
sayHelloPaul();

We can tidy this up by using Function.prototype.bind:

bind.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
var Person = function(name) {
  this.name = name;
};

var sayHello = function() {
  console.log("Hello, my name is " + this.name);
};

var bob = new Person('Bob');
var paul = new Person('Paul');

var sayHelloBob = sayHello.bind(bob);
var sayHelloPaul = sayHello.bind(paul);

sayHelloBob();  // Hello, my name is Bob
sayHelloPaul(); // Hello my name is Paul

Lines 12 and 13 use bind to create a new function that when called, has its this value set to whatever the given value between the parenthisis is.

It is worth mentioning that if you want to use bind in older browsers then you still can by using a polyfill such as this and I would emplore everybody who is reading this to do just that if you are not already doing so.

Partial Functions

What is less known about bind is that we can use it to make a function with pre-specified initial arguments. These arguments if supplied, follow the provided this value and are inserted at the start of the arguments passed to the target function.

Let me illustrate this with an example, the code below contains a chain of promises with almost identical resolve handlers. I know I could use RSVP.hash for this but I am merely illustrating the point:

chain.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
var self = this;

return getJSON('/login').then(function(auth) {
  self.auth = auth;

  return getJSON('/users');
}).then(function(users) {
  self.users = users;

  return getJSON('/contacts');
}).then(function(contacts) {
  self.contacts = contacts;

  return getJSON('/companies');
}).then(function(companies) {
  self.companies = companies;

  return resolve(self);
});

On lines 4, 8 and 12 of the above gist, I am setting a property of the self reference to the data returned from the async call and on lines 6, 10 and 14 I am calling getJSON with a different url that will return the next resource. The only things that are different are the property name and the string literal for the next url.

The function below would DRY this up nicely:

DRY.js
1
2
3
4
5
var continuer = function(prop, nextUrl, data) {
  this[prop] = data;

  return getJSON(nextUrl);
};

The only problem I have is that the above function’s argument list does not fit into my resolve handlers argument list where only one argument is passed containing the result of the async call. The answer is of course to use bind and specify some pre-specified initial arguments:

continuer.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
var self = this;

var continuer = function(prop, nextUrl, data) {
  this[prop] = data;

  return getJSON(nextUrl);
};

var setAuth = continuer.bind(self, "contacts", "/users");
var setUsers = continuer.bind(self, "users", "/contacts");
var setContacts = continuer.bind(self, "contacts", "/companies");

return getJSON('/login')
  .then(setAuth)
  .then(setUsers)
  .then(setContacts)
  .then(function(companies) {
    self.companies = companies;

    return resolve(self);
  });

On lines 9 - 11, I am supplying some pre-specified arguments to the bind function that will be bound to the first two arguments of the continuer function when the specific instances are called. I think this DRYs up things quite nicely.