The Software Simpleton

Nomadic cattle rustler and inventor of the electric lasso

Functional JavaScript in the Browser and Why I Should Care

Why should you care about functional javascript? I’d heard of the merits of functional programming for a while now and up until recently, I thought that the main benefits of functional programming where really only applicable when dealing with highly concurrent programs when functional programming can help guarantee thread safety. Writing side effect free functions that use immutable data structures rules out interaction problems between threads that mutate data. All well and good but why should I care about any of this in the single threaded realm of the browser?

The pendulum between server heavy app and client heavy app. has swung back to the client again for this epoch and single page applications are all the rage. This would have seemed like insanity at the turn of the century but advances in browser technology and a demand for more ambitious applications has led us to the now infamous SPA. Our programs live a lot longer in the browser than they used to. Gone are the days when we could rely on a browser refresh to reboot the browser code and rebuild clear all our objects from memory. reactjs has come up with a beautfiul top down, one way data push that can simulate this behaviour by abstracting away that gargantuan side effect known as the DOM into a virtual DOM to diff against the previous state. Reactjs has embraced functional programming and so should you.

Side effects, function Purity and Referential Transparency

Functional programming favours functions that, for a given input, will consistently return the same output. A pure function does not depend on and does not modify the state of variables outside of its scope. When a function performs any other action, apart from calculating its return value, the function is impure. A program or function is said to have side effects if it can produce different outputs given the same input.

A very simple example of a pure function is below:

mult.js
1
const mult = (a, b) => a * b;

Referential transparency is the ability to freely replace an expression with its value and not change the behaviour of the program. We can show that the mult function is both pure and referentially transparent with the code below:

rf.js
1
2
3
4
5
6
7
8
9
const mult = (a, b) => a * b;

const result = mult(2, 3) + mult(4, 5);

const result1 = 6 + mult(4, 5);

const result2 = 6 + 20;

console.log(result == result1 == result2);

Replacing the call to mult with the result does not alter the output of the computation.

Below is an example of a function that relies on a global variable to calculate its output:

sideeffect.js
1
2
3
4
5
6
7
8
9
10
11
12
let number = 0;

const inc = (n) => {
  number = number + n;

  return number;
}

const result1 = inc(1);  //=> 1
const result2 = inc(1);  //=> 2

console.log(result1 === result2);

We can clearly see that providing the same input each time does not give us the same output each time.

Side effects are functions that rely on the outside OR can be functions that alter the outside world. The ubiquitous Hello World program is actually a side effect because it alters the state of the output on the screen. A call to console.log is a side effect. All IO is side effect laden, reading a file from a disk is a side effect because it might throw an exception because the network is unavailable. We therefore cannot guarantee the result of calling the function.

Any function that does not return a value will more than likely have side effects because it is probably mutating some external state.

Our programs would not be very practical without side effects and the goal of functional programming is not to eliminate side effects but instead we want to limit them and also more importantly, isolate them. How can we limit side effects in the sea of mutation that is javascript? The first thing we can do is to use immutable data structrues.

Immutable Data Structures

I think the penny is starting to drop with many in the javascript world about how sensible immutable data structures are. A data structure is immutable if it cannot be changed after it has been created.

In the chaotic realm of the single page application, I find it very reassuring to know that after I have created an object or assigned a value to a variable, it will not be changed by some well meaning code outside of my control. A lot of SPA frameworks use two way data binding to bind objects to DOM elements or other structures. I have also had hellish results with using observation through Object.observe or some other mechanism of reacting to state changes, I now consider this to be an anti-pattern.

es6 has introduced the const keyword which is analogous to final in java, it does not mean that all data structures defined with the const keyword are immuable but it does mean they cannot be reassigned once they have been assigned. The code sample below will illustrate this:

const.js
1
2
3
4
5
6
7
8
9
10
11
const number = 3;

number = 4; // => error: Attempting to override 'number' which is a constant.

const person = {name: 'Paul Cowan'};

person.name = 'Bob Cowan'; // mutate away

console.log(person.name);

person = {name: 'Paul Cowan'}; //=> error:  "person" is read-only

If we want full immutability then we can use something like immutable-js or mori. Both libraries provide persistent data structures for your use. The data structures are called persistent because they always presist a previous version of themselves when modified.

Below is an example of immutable-js that illustrates this:

immutable.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
let list1 = Immutable.List.of(1, 2);
let list2 = Immutable.List.of(1, 2);

console.log(Immutable.is(list1, list2) === true);  // => true, equality by value and not reference

let map1 = Immutable.Map({a: 1, b: 2, c: 3});
let map2 = map1.set('b', 2);

console.log(map1 === map2); // => true, map2 returns a reference to map1 because no change was made

let map3 = map1.set('b', 50);

console.log(map1 !== map3);

console.log(map1.toJS()); //=> {a: 1, b: 2, c: 3}, map1 is unchanged
console.log(map3.toJS()); //=> {a: 1, b: 50, c: 3}

You can see from the above that we can check equality by value and not reference on line4 when comparing list1 and list2.

Also illustrated is how map2 returns a reference to map1 on line 7 because no change was made to the underlying hash and on line 11, map1 remains unchanged and a new version of the data structure is returned after changing or adding a new value to part of the data strurcture. I hope you can see how we could use persistent data structures to trivially hookup undo and redo functionality (more on this later).

Statelessness

Imperative programming works by changing programming state to produce answers. Conversely, functional programming produces answers through stateless operations.

This brings us back to function purity, our programs are easier to reason about if we can be sure that given the same input, we get the same output. We want to avoid functions that reference member variables or any thing outside of the functions environment wherever possible.

Back to the Real world

Here are some things to consider everytime you create a function in javascript:

  • Are my functions dependant on the context in which they are called, or are they pure and independent?
  • Can I write these functions in such a way that I could depend on them always returning the same result for a given input?
  • Am I sure that these functions won’t modify anything outside of themselves?
  • Pass values as parameters, don’t store state in member variables.

I blogged here here about using a real world example to limit side effects in an emberjs application and here about how you can use persistent data structures in an emberjs application to implement basic undo and redo functionality.

Higher Order Functions

A higher order function is either:

  • A function that takes a function as an argument
  • A function that returns a function

I am going to concentrate on the latter and I am going to first of all use partial application.

Wikipedia gives the following definition of partial application:

partial application (or partial function application) refers to the process of fixing a number of arguments to a function, producing another function of smaller arity

If we return to our mult function that I showed in the beginning, we can create a new function double by using partial application:

double.js
1
2
3
4
5
const mult = (a, b) => a * b;

const double = mult.bind(null, 2);

console.log(double(3)); // => 6

On line 3 of the above, I am using the lesser known property of bind that after the first argument where you can specify a context, every parameter after the first will be prepended to the list of parameters when invoking the bound function.

We could rewrite the double to return a function like this:

double2.js
1
2
3
4
5
6
7
8
9
10
11
const mult = (a, b) => a * b;

const makeMultiplier = (a) => {
  return (b) => {
    return mult(a, b);
  }
}

const double = makeMultiplier(2);

console.log(double(3)); // => 6

We now have a makeMultiplier that can create many different types of functions based on mult.

A more practical use of a higher order function is the maybe function below that can take a function and return a null safe version:

maybe.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
const maybe = (fn) => {
  return (input) => {
    if(!input) {
      return;
    }

    return fn.call(this, input);
  };
};

const toLower = i => i.toLowerCase();

console.log(toLower("henry"));

let nullString;

console.log(toLower(nullString)); // TypeError: Cannot read property 'toLowerCase' of undefined

const nullSafeToLower = maybe(toLower);

console.log(nullSafeToLower(nullString)); // returns undefined, no exception

Here we create a new null save function that is returned from the maybe function. We can now create other functions from this maybe function that will handle null values.

Composability

Another benefit of higher order functions is to take 2 or more functions and combine them into one. Below is an and function that will perform a logical and on the output of two functions:

and.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
const isEven = (number) => number %2 === 0;

const isPositive = (number) => number >= 0;

const and = (f, g) => {
  return function() {
    return f.apply(this, arguments) && g.apply(this, arguments);
  }
};

isPositiveAndEven = and(isPositive, isEven);

console.log(isPositiveAndEven(5)); // => true
console.log(isPositiveAndEven(-4)); // => false

Further down the rabbit Hole

There are a number libraries that go much further with respect to functional programming:

  • omniscientjs
    • Built on top of reactjs
    • Top down rendering
    • Immutable Data
  • OM
    • Built on top of reactjs
    • Written clojurescript
    • ClojureScript’s immutable data types
  • Purescript
    • Inspired by haskell
    • Type system
    • Bindings for reactjs and angular
  • Elm
    • Compiles to HTML and javascript
    • Compiler guarantees no runtime exceptions

Clojure - Idiomatic Refactor From Recursion

I’ve become addicted to solving programming challenges that you might find at hackerrank or 4clojure. I spend most of my day job in emberjs and as much as I find myself agreeing with reactjs's take on things, I simply don’t have the energy or the will to learn another javascript framework. I also think it is bad to learn another way to do the same thing in your spare time. You need to push your brain into interesting and new avenues.

I’m using clojure to solve these programs and it is quite nice to not have to worry about persisting data or learning the latest du jour framework.

I have found myself using the same pattern over and over again when iterating a sequence that might decrease due to some condition and accumulating a value while doing this. Below was my bog standard way of doing this:

recursion.clj
1
2
3
4
5
6
7
(defn process [acc sticks]
  (let [smallest (apply min sticks)
        cuts (filter #(> % 0) (map #(- % smallest) sticks))]

    (if (empty? cuts)
      acc
      (process (conj acc (count cuts)) cuts))))

The above code reduces each item in the sequence by the smallest value and then filters out any values that are zero or less (lines 2 and 3). If there are any values left, the function recursively calls itself until the sequence is empty. On each call to the function, the count of remaining elements in the sequence is added to an accumulator argument acc.

I have been using this pattern for a while now but it did not seem to me to be idiomatic clojure. I did some research and the refactoring below is a huge improvement in terms of modularity, readibility and being more idiomatic:

iterate.clj
1
2
3
4
5
6
7
8
(defn cuts [sticks]
  (let [smallest (apply min sticks)]
    (filter pos? (map #(- % smallest) sticks))))

(defn process [sticks]
  (->> (iterate cuts sticks)
       (map count)         ;; count each sticks
       (take-while pos?))) ;; accumulate while counts are positive

The first step was to isolate in a new function the logic that performs the filtering on the sequence. I have created a cuts function on line 1. This improves the modularity.

The process function on line 5 uses the thread last macro. Both the thread macro -> and the thread last macro ->> make the code easier to read by allowing you to use an imperative style rather than nesting the calls. The thread last macro inserts the first argument that you pass to it as the last argument to each of the forms. Below are some simpler examples of the thread last macro that should illustrate how the argument fills in the last argument for each of the forms:

last.clj
1
2
3
4
5
6
7
8
9
10
(->> x
     f)
;; (f x)
(->> x
     f
     g)
;; (g (f x))
(->> x
     (f y))
;; (f y x)

If we return to our example, we can use macroexpand to expand out the macro to its nested reality:

macro.clj
1
2
3
4
(macroexpand '(->>
              (iterate cuts [1 2 3 4 3 3 2 1])
              (map count)
              (take-while pos?)))

Below is the output of the macroexpand call:

result.clj
1
(take-while pos? (map count (iterate cuts [1 2 3 4 3 3 2 1])))

The first argument in this case is supplied via the iterate function on line 6 that generates an infinite lazy sequence by taking two parameters, a function and a seed value. The seed value in this case is the vector [1 2 3 4 3 3 2 1] and this is initially passed to the cuts function. iterate will then infinitely call cuts passing in as an argument, the previous call to cuts.

map is used to apply a function to each item returned from the iterate form and we use count as the function to transform the result of each call to cuts. take-while is used to constrain the infinite nature of iterate and as soon as the pos? function returns false, the results are returned to the calling function. We use pos? to check whether there are are any elements that are not zero. take-while will also accumulate the count results and return them to the calling function instead of using an accumulator argument like I used in my original example.

I really like how this turned out and it is definitely more idiomatic clojure than my original version and I think this is a good barrier to get past in my journey into clojure.

Emberjs - Computed Properties and Promises…..don’t

A question I see coming up time and time again is how to return a resolved promise from a computed property.

There are a number of ways of doing this and I, like many have tried to solve this problem myself before realising that it is not a path you should go down.

I can flesh this out with an example that I originally solved using a computed property that resolved a promise.

I inherited a nasty bit of code on the server or API side of the project that I was working on that stored the relationship of different types af object in a generic postgres database column that used serialized yaml as the format to compound the uselessness. This is particularly wrong for a number of reasons such as you can’t query the sucker unless you use regular expressions. It is completely unmaintainable and you should never, ever do this and Edgar F. Codd who gave us relational database theory would be turning in his grave.

An example where this was used is in a user’s activity feed that contains audited events for a user of the application. For example if the user or contact sent an email then their activity feed would contain an item like this:

1
2
3
4
5
6
7
8
{
"activities": [{
    "id":210849,
    "tag":"user",
    "event":"sent_email",
    "time":"2015-06-06T17:01:51Z",
    "meta":{"email_id":607149}
}]

The meta field on line 7 comes from the serialized yaml column and is used as a generic bucket that can contain different types of relationships or other junk, making it extremely difficult to work with. The answer to how to deal with this is refactor the server code and never, ever use serialized YAML but if you are stuck with this type of nonsense then how would you satisfy the email property of the template below? We need to somehow or somewhere load the email instance from the meta.email_id property.

When I first encountered this problem, my answer was to use a computed property that resolved a promise and then set itself:

cp.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
email: Ember.computed('activity.meta.email_id', function(){
  var store = this.get('store'),
      emailId = this.get('activity.meta.email_id'),
      self = this;

  if(!emailId) {
    return;
  }

  store.find('email', emailId).then(function(email) {
    self.set('email', email);
  }).catch(function(error) {
    //handle error
  });
})

On line 11 of the above, I set the property when the property resolves.

This will more or less work and here is a jsbin that shows an example of how to do this.

There are a number of things wrong with this approach, namely we are trying to treat something that is inherently synchronous in an asynchronous manner. The cp will fire a number of times due to the promise resolving and I have had a lot of pain with ember and observing dependent keys. This can lead to the property referencing a partially resolved object or you can get cascading events on other cps and observers that reference a key firing in a sometimes recursive manner. These are situations I now avoid like the plague and if you have any sense, you will heed my battle weary tone and avoid them too.

I’ve also seen computed properties that reference promise objects or have dependent keys on the state of the promise, but that is far too contrived to be credible and will lead to pain. You will have partially resolved data and cascading events triggered. Don’t do this.

I develop with ember a lot different now than I did this time 12 months ago.

If you feel you need a computed property that will resolve a promise and you have read this, the answer is…….DON’T.

So what do we do?

Subscribing to data events throughout your application by using observers or waiting for computed property keys to update and trigger actions creates overhead but more importantly makes your application difficult to reason about and in my experience causes unreliable and inconsistent behaviour for reasons I have been writing about for a while now.

When data is passed from above rather than being subscribed to, we can react only when we know something has changed. React’s flux has popularised the top down approach and it makes nothing but sense.

So the answer is to let the resolved property be passed in from above in a top down fashion rather than listening for it to happen. Ember is on board with this philosophy and it goes by the meme data up and actions down although I think this could do with some better fleshing out.

So the first refactoring is to create a service that will be charged with resolving the activity instance and taking care of unwrapping this horrible meta hash that can contain all kinds of junk. I want this encapsulated and ready to use anywhere in my code. With this in mind, I have created an ActivityService that is injected into all components through this initializer:

initialize.js
1
2
3
4
5
6
7
8
9
10
11
12
Ember.Application.initializer({
  name: 'load-services',
  initialize: function(container, application) {
    var activityService = App.ActivityService.create({
      store: container.lookup('store:main')
    });
    application.register('activity-service:current', activityService, {
      instantiate: false
    });
    application.inject('component', 'ActivityService', 'activity-service:current');
  }
});

A scaled down version of the ActivityService is below that takes care of loading the activity and unpacking this now infamous meta field:

activity_service.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
App.ActivityService = Ember.Service.extend({
  resolveActivity: function(activityId) {
    var self = this,
        store = this.store;

    return new Ember.RSVP.Promise(function(resolve, reject) {
      store.find('activity', activityId).then(function(result) {
        var activity = result.shallowCopy();

        store.find('email', result.get('meta.email_id')).then(function(result) {
          activity.email = result.shallowCopy();
          resolve(activity);
        });
      });
    });
  }
});

The above code returns a promise that when resolved, will return a simple hash rather than the resolved ember-data instance. I prefer not to bind or work directly with the ember-data instances and I discussed this the benefits of this in this post. I have created a simple shallowCopy extension to the DS.Model class that creates a shallow copy of the ember-data instance:

shallowcopy.js
1
2
3
4
5
6
7
8
9
10
11
12
13
DS.Model.reopen({
  shallowCopy: function(){
    var type = this.constructor,
        self = this,
        hash = {};

    type.eachAttribute(function(key, meta) {
      hash[key] = self.get(key);
    });

    return hash;
  }
});

In the original example, I iterated over the user’s activities like this:

I will replace this with a component:

The ActivityFeedComponent creates an array of activity hashes by calling out to the ActivityService and only pushing the resolved instances onto the activities array when the service has done what it needs to do:

ActivityFeedComponent.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
App.ActivityFeedComponent = Ember.Component.extend({
  activities: Ember.A(),
  _initialize: Ember.on('init', function(){
    var self = this;

    this.get('user.activities').forEach(function(a) {
      self.ActivityService.resolveActivity(a.get('id'))
      .then(function(activity){
        self.get('activities').addObject(activity);
      }).catch(function(error) {
        // handle error
      });
    });
  }),
  _tearDown: Ember.on('willDestroyElement', function(){
    this.get('activities').clear();
  })
});

This will give me so many fewer problems than resolving the promise in a computed property as I did in the original example. I only push onto the activities array when the service has done what it needs to do. I am also working with copies of the ember-data instance which will curtail any unwanted side effects that I might encounter. I will sleep better with this code.

The activity-feed component’s template simply looks like this:

Here is a jsbin that brings it all together.

So my message is clear, don’t resolve promises in your computed properties, nor should you have dependent keys on isFulfilled as I see some advocating.

You have been warned.

Emberjs - Avoiding Side Effects…. Or at Least Trying

I’ve been using ember for 2+ years and the more I deal with a single page application that exists in memory for an indeterminate length of time, the more tenets of functional programming I embrace to bring some sanity to the chaos. The problem with ember is that it is more class or object based than functional.

The move to ember 2.0 will see ember become more functional but I think it needs to go further and drop a lot of the class based paradigms to make it more robust.

I’ll quickly run through the important tenets that could make your code more robust if you can employ them:

Function Purity

You should always strive to make your functions as pure or side effect free as possible. Wikipedia gives the following definition for a pure function:

A pure function is a function where the return value is only determined by its input values, without observable side effects

Another way of expressing the above is that a pure function will always return the same value when given the same arguments.

Below is the most basic of basic examples of a pure function

pure.js
1
2
3
function addOne(num) {
  return num + 1;
}

This function is pure because it will always return the same result, given the same input. It only reads local variables and it only writes to local variables. This is also sometimes referred to as referential tranparency because the expression can be changed with its value without effecting the behaviour of a program. For example if we used the addOne function like this:

ref.js
1
addOne(1) + addOne(1); //=> 4

We can replace the expression with its value and still get the same result:

replace.js
1
2
3
2 + addOne(1); //=> 4

2 + 2; //=> 4

A simple example of an impure function is below:

sideeffect.js
1
2
3
4
5
6
7
8
var number = 2;

var sideEffect = function(n) {
  number = n * 3;
  return number * n;
}

sideEffect(3);

The side effect of this function is that it changes the value of the number variable each time it is executed. The example above is not referentially transparent because if we call sideEffect with 3 we would get a different result each time.

On the surface dealing with only pure functions is very limiting, we would need to avoid things like new Date or Math.Rand because they always return a different value. console.log is also on the banned list because it accesses a global variable. In fact, any function that takes an object as an argument is potentially subject to impurity. The DOM is one big huge stateful side effect waiting to happen.

The bottom line is that if you are dealing with javascript, you will always be dealing with some degree of impurity or our programs would not be very useful. What we need to do is try and minimize this.

Ember’s Handelbars helpers can be pure functions but I have seen an RFC recently that wants to add all sorts of state and life cycle events which is something that made me shudder. I worry that if this rfc is pushed through then it will complicate something that is very useful and can be side effect free.

Purity and Idempotence

Idempotence entered the vernacular or at least resurfaced when REST went mainstream. An idempotent operation is one that has no additional effect if it is called more than once with the same input parameters. For example moving an item from a set can be considered an idempotent operation or deleting a record by GUID is idempotent becuase the row stays deleted.

Purity and idempotence are completely orthogonal, a pure function does not have to be orthogonal and vice versa. An idempotent function can cause idempotent side effects, a pure function cannot.

Immutability

In functional prograaming, the ideal situation is that there is never mutation. I blogged previously about some of the benefits of immutability and gave an example of how it might be used.

One of the traps I fell down when I first started developing with ember was to observe changes on mutable arrays like this.

observe.js
1
2
3
arrayDidChange: Ember.computed('myArray.[]', function() {
  // do stuff
}

I see this type of code in a lot of stackoverflow answers and blog posts but I now consider this to be an antipattern. Two way databinding was one of the things that first drew me to ember but ended up causing me no end of pain. I think two way databinding still has its place for binding simple literals like an input’s value attribute to a string prop of a value but binding object to object causes pain. I believe in ember 2.0, binding will be one way only by default and this is the right move. You can stop this now by ensuring you use Ember.computed.oneWay instead of Ember.computed.alias.

alias.js
1
2
3
4
5
6
7
// good
prop: Ember.computed.oneWay('attr', function() {
}

//bad
prop: Ember.computed.alias('attr', function() {
}

Update

As Charles Lowell rightly pointed out in the comments, it is possible to create readonly computed properties that will raise an exception if a set is an attempted.

readonly.js
1
2
prop: Ember.computed.readOnly('attr', function() {
}

I’ll certainly be using this from now on.

One of the benefits of immutability is that diffing is done by value and not by reference, just think how easier diffing javascript would be if the following was true out of the box:

diff.js
1
[1, 2, 3] === [1, 2, 3] //=> sadly false;

Libraries like om in clojurescript use diffing on their immutable datastructures to great effect to negate needless re-renders with reacts virtual DOM.

But the main reason that I am starting to see the main use case for immutability is that, it makes your code much easier to reason about and you can avoid side effects using immutable data structures. For me, the biggest thing about using immutable data structures is that I am completely safe from some unkown mutation happening which in a long running single page application is great for my peace of mind. I’ve been surprised too many times in the past.

You don’t have to use a library like seamless-immutable but you should try and tranfrom or create new objects or arrays rather than mutating existing objects. You should favour map or filter over forEach, forEach must have a side effect somewhere to accomplish anything. The only time I would use forEach is for something like this:

forEach.js
1
arr.forEach(function (item) { console.log(item); });

Statelessness

Imperative programming works by changing programming state to produce answers. Conversely, functional programming produces answers through stateless operations.

A good example of the contrast is looping, an imperative approach is to use looping:

loop.js
1
2
3
4
5
6
var loop = function() {
    for (var x = 0; x < 10; x += 1) {
        console.log(x);
    }
};
loop();

The loop produces its results by constantly changing the value of x. A functional approach would use recursion:

recursion.js
1
2
3
4
5
6
7
8
9
10
var loop = function(n) {
    if (n > 9) {
        console.log(n);
        return;
    } else {
        console.log(n);
        loop(n + 1);
    }
};
loop(0);

Functional programming requires us to write stateless expressions and keep our data immutable.

Back to The Real World……and Ember

If you perform a google for functional javascript you will get plenty of examples of sorting lists or simple number crunching. I have found very little about how to use functional techniques for the type of situations you face on a day to day basis as a web dev or your ongoing battle with the DOM. So I am going to use a real world example that I worked on within the last week of writing this blog post.

The last thing I worked on was a custom query builder where the user builds a query on the fly from the html elements he is presented with. Query items can be added and removed: If I had attempted something like this 12 months ago, I would have used rampant mutation, observers and two way binding in a huge chaotic side effect soup. I have my battle scars and I see the world differently. I will now detail my solution. I have created this jsbin that you can play along at home with and is a pretty damn accurate duplicate of how I solved this.

The truth of the matter is that ember is very, very, very stateful and adheres more to a class or object based methodology. If you want to reference data structures in your templates then you need to create member properties and reference them.

My goal for any new piece of code that I create is to keep things as side effect free as possible. I will most definitely never use the Ember.observer primitive, I use few computed properties if any and rarely use two way databinding. I will work with immutable copies of anything persistable. I want to keep surprises to a minimum and I want to keep things in my control and not be working or waiting for the run loop which is outside of my control.

In this custom query example, there is only ever one active query that you are manipulating, you are either building a new one or you are updating an existing query. These queries are persistable and I have modelled it as a parent query that contains a child collection of query parts. Here is the ember data CustomQuery definition:

CustomQuery.js
1
2
3
4
App.CustomQuery = DS.Model.extend({
  name: DS.attr('string'),
  queryParts: DS.hasMany('queryPart', {async: true})
});

And here is the queryPart:

queryPart.js
1
2
3
4
5
App.QueryPart = DS.Model.extend({
  field: DS.attr('string'),
  operator: DS.attr('string'),
  value: DS.attr('string')
});

My main goal for working with instances of these ember-data models is to not work with them. I am going to create copies of the data structure and work with those and only copy them back into the models when I want to persist anything. The last thing I am going to do is to use two way databinding to bind directly to the model properties. I have been down that path and it is the road to hell.

At any one time, we are dealing with a collection of query parts and we have query-builder component to add and remove query parts. Below is a screenshot of how the elements look:

The IndexRoute in the jsbin, either creates an empty array and assigns it to a queryParts variable that is passed to a query-builder component, or if we are dealing with a persisted query from the models above then we create a raw hash to pass to the component:

indexroute.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
App.IndexRoute = Ember.Route.extend({
  model: function(params, transition){
    var queryParts = {};

    if(params.query) {
      var query = this.store.all('customQuery').find(function(c){
        return c.get('id') === params.query;
      });

      queryParts = query.get('queryParts').toArray().map(function(part){
        return {
          field: part.get('field'),
          operator: part.get('operator'),
          value: part.get('value')
        };
      });

      this.controller.set('queryParts', Ember.A(queryParts));
    } else {
      this.controllerFor('index').set('queryParts', Ember.A());
    }

    return Ember.RSVP.hash({
      contacts: this.store.find('contact', {query: queryParts}),
      customQueries: this.store.find('customQuery')
    });
  },

The user can navigate to the IndexRoute via a link that will have the custom query id in the query params that you can see on line 5 of the above code. I am creating a hash rather than using the ember-data model directly to keep things side effect free. I have already made my life much easier.

Here is the how query-builder component is referenced on the parent template or the index template in the jsbin. The binding of the queryParts that are passed into query-builder are sadly still two way bound at this time of writing with ember 1.11.1 but we will work with them as if they were one way bound.

Below is the template for query-part.hbs:

On lines 2 to 4, a query-part component is rendered for each part of the query. The template for query-part.hbs is below:

The query-part component will fire off queries in response to either user input in the textbox or changing the query part operator in the dropdown.

Below is the code for the query-part component

query-part.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
34
35
36
37
38
39
40
41
App.QueryPartComponent = Ember.Component.extend({
  actions: {
    changeOperator: function() {
      this.sendQuery();

      return false;
    },
    removeQueryPart: function(index) {
      this.sendAction('removeQueryPart', this.get('index'));
    }
  },
  sendQuery: function() {
    Ember.run.debounce(this, 'executeQuery', 300);
  },
  executeQuery: function() {
    var self = this;

    Ember.run.next(function() {
      if(!self.$('input[type=text]')) {
        return;
      }

      var q = Immutable(self.get('queryPart')),
          value = self.$('input[type=text]').val() || '',
          operator = self.$('.operatorSelector').val(),
          index = self.get('index');

      if(!value.length) {
        return;
      }

      self.sendAction('modifyQuery', q.merge({operator: operator, value: value}), index);
    });
  },
  keyDown: function(e) {
    if(e.keyCode === 13) {
      return false;
    }

    this.sendQuery();
  },

We want to adhere to data down and actions up. So queries are bubbled up from this component to the controller.

If input is entered into the text input, the keyDown handler on line 35 calls sendQuery on line 12 that will debounce a call to executeQuery.

The code in executeQuery on lines 15-34, could definitely be accused of being more jQuery than ember. If that is the case, then I am guilty as charged. I am using simple selectors to extract the values from the element rather than relying on two way databinding. I don’t want any surprises about values not being sync’d, I just want to extract the values from the elements when the query is run. There really is no need for it to be any more complicated than that.

I then bubble the newly constructred immutable data structure up to the parent component by calling the modifyQuery action. I don’t necessarily need these structures to be immutable but I want to guard against any side effects I might encounter unexpectedly. This action is then bubbled up to the controller where a it uses the raw hash to execute a findQuery on the main data that the query is filtering:

runcustomQuery.js
1
2
3
4
5
6
7
8
runQuery: function(queryParts) {
  var self = this;

  this.store.find("contact", {query: queryParts})
    .then(function(results){
      self.set('contacts', results);
    });
  }

When it comes to saving the query, the query-builder component calls a saveCustomQuery action on the parent controller, passing the raw array of query parts which are plain old javascript objects and either creates a brand new CustomQuery model and persists it or overrides the existing queryParts collection of the existing instance:

saveQuery.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
saveCustomQuery: function(){
  var self = this,
      all = this.store.all('customQuery').toArray(),
          customQuery;

  if(!this.query) {
    var queryName = "Query " + (all.length + 1).toString();

    customQuery = this.store.createRecord("customQuery", {name: queryName});
  } else {
    customQuery = all.find(function(c) {
      return c.get('id') === self.query;
    });

    customQuery.get('queryParts').clear();
  }

  this.get('queryParts').forEach(function(part){
    customQuery.get('queryParts').createRecord(part);
  });

  customQuery.save().then(function(result){
    self.transitionToRoute('index', {queryParams: {query: result.get('id')}});
  });
}

There are only 2 parts in this piece of functionality where I deal with the actual ember-data instances. The first is when I am creating copies of the structures to feed to the components and here when I am persisting the changes back to the server.

Epilogue

Congratulations if you made it this far, this is a long post. Staying side effect free and dealing with pure functions is next to impossible when working with something as stateful as the DOM. Ember also is very stateful and class based. I’ve used a real world example because there is no better example to illustrate just how challenging it is. I have 100% failed on the pure function front. But I’ve tried to stay as side effect free which for me means dealing with copies of anything persistable, avoiding observers, computed properties and two way data binding wherever possible. I’ve tried the other way and it is not pretty. The code I’ve described will give me a lot less headaches than other ways I might approach this.

I’m interested to see if we can take a much more functional approach with ember 2.0 but the rfc that wants to pollute handlebars helpers with state and life cycle events is not a step in the right direction.

I’ve heard of the benefits of functional programming for years but I now realise how sensible they are and how they lead to more robust code. When working in the chaotic world of the single page application, they make nothing but sense.

I would love any feedback at all on this. Good or bad, state your case.

Emberjs - fillIn Test Helper With Key Events

I’ve imposed a self enforced ban on using observers when using ember. For example, I previously used two way binding in my template to bind the value attribute of an input element to a property

I would then create an observer on this bound value like this:

observer.js
1
2
3
queryDidChange: Ember.observer('query', function(){
  //some transofomation
}

This has generally led to a world of pain that I lamented about in this post.

What I do now in this situation is use something like the input DOM event:

input.js
1
2
3
4
5
  input: function(e) {
    var query = e.target.value || '';

    set(this, 'query', query);
    //do stuff

I can do any transformations in this event handler without the pain of obsevers or 2 way binding, I am in control of what is happening.

This is all well and good but what is not good is that this is not testable with the current ember test helpers.

There is the fillIn test helper but this will just set the value of an input to the supplied string without raising any key events:

fillIn.js
1
2
3
4
5
6
7
8
function fillIn(app, selector, contextOrText, text) {
  //init code

  run(function() {
    $el.val(text).change();
  });
  return app.testHelpers.wait();
}

What I needed was a way for the appropriate key events to be raised after every character. I might also have code in keydown and keyup for example.

With this in mind, I created this test helper to meet my requirements:

fillInWithInputEvents.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
34
35
36
37
38
39
40
41
42
43
function fillInWithInputEvents(app, selector, contextOrText, textOrEvents, events) {
  var $el, context, text;

  if (typeof events === 'undefined') {
    context = null;
    text = contextOrText;
    events = textOrEvents;
  } else {
    context = contextOrText;
    text = textOrEvents;
  }

  if (typeof events === 'string') {
    events = [events];
  }

  $el = app.testHelpers.findWithAssert(selector, context);

  $el.val('');

  focus($el);

  function fillInWithInputEvent(character) {
    var val = $el.val();
    var charCode = character.charCodeAt(0);

    val += character;

    run(function() {
      $el.val(val).change();
    });

    for (var i = 0, l = events.length; i < l; i++) {
      run($el, "trigger", events[i], { keyCode: charCode, which: charCode });
    }
  }

  for (var i = 0, l = text.length; i < l; i++) {
    fillInWithInputEvent(text[i]);
  }

  return app.testHelpers.wait();
}

The above helper will input the text one character at a time and raise any supplied events.

For example if I only want to raise an input event with each character then I would use it like this:

single.js
1
2
  visit('/')
    .fillInWithInputEvents('input.autosuggest', 'Michael', 'input')

Or if I want to raise more than one event then I can supply an array of input events:

multiple.js
1
2
  visit('/')
    .fillInWithInputEvents('input.autosuggest', 'Michael', ['input', 'keydown'])

You can use the helper like this in an ember-cli test-helper and I have created this pull request to get it included with the ember source.

Emberjs - Action Maker

I am currently working on an ember project using 1.7.1 and I’ve reached the point of no return with regard to passing action names down a component hierarchy and then bubbling them back up using sendAction. I believe the problem is still present in recent versions of ember and we need to somehow make this more user friendly.

I will illustrate the problem with an easily grokked todo example before giving a couple of solutions.

Here is a list of todos:

Here I am creating a todo-list component and specifying an action that I want called when a todo is checked to signify it is finished.

Below is a route with a finishTodo action that is referenced in the above code sample:

daddy.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
App.IndexRoute = Ember.Route.extend({
  actions: {
    finishTodo: function(todo) {
      console.log('in root');
      todo.set('isFinished', true);
      todo.save().then(function(){
        console.log('finished');
      });
    }
  },
  model: function(){
    return this.get('store').find('todo');
  }
});

All good so far but with the current state of data down and actions up, I need to pass this action name down to each child component that would use sendAction to call it.

In the example, I need to specify the action name in each todo-item component that the todo-list component creates:

I then need to bubble this up from the child todo-item component:

todo-item.js
1
2
3
4
5
6
7
8
9
App.TodoItemComponent = Ember.Component.extend({
  actions: {
    finishTodo: function(todo) {
      console.log('in child');

      this.sendAction("action", todo);
    }
  }
});

This gets bubbled up to the todo-list component that uses sendAction to bubble this up to the route:

todo-list.js
1
2
3
4
5
6
7
8
9
App.TodoListComponent = Ember.Component.extend({
  actions: {
    finishTodo: function(todo) {
      console.log('finish in parent component');

      this.sendAction("action", todo);
    }
  }
});

Here is a jsbin that shows the up and down duplicity in its entirety.

One sure sign of tight coupling is the number of places/files that you need to change for one method name change. As developers, we should be seeing this type of thing as a red flag that requires attention.

One way round this is to create a helper to package up the action, the context and any arguments that are needed to call the action. This can be achieved with a handlebars subexpression and a handlebars helper.

I can refactor the todo-list component to this:

The above code uses a handlebars subexpression to create a method named action on each todo-item component, I pass in the targetObject which in this case is the controller but you can reference anything that is accessible and has an actions hash, I also pass the action name I want called and any additional arguments.

The subexpression calls this handlebars helper that returns a higher order function:

makeAction.js
1
2
3
4
5
6
7
8
Ember.Handlebars.registerBoundHelper('makeAction', function() {
  var context = arguments[0],
    args = Array.prototype.slice.call(arguments, 1 , -1);

  return function() {
    return context.send.apply(context, args);
  };
});

I can then call this action in the todo-item component:

1
2
3
4
5
6
App.TodoItemComponent = Ember.Component.extend({
  change: function(e) {
    var todo = this.get('todo');
    this.action(todo);
  }
});

Here is a jsbin of the above.

This makes things a little more sane for me and I can eliminate a lot of code. Another alternative that I am considering is to enhance the global event bus I previously blogged about.

The alternative is to carry on with what is currently on offer but I’ve just reached my limit with that.

Emberjs - Simple Global Event Bus

Following on from my last post about Communication Between Components, somebody rightly pointed out in the comments that another way of doing this is to create a global event bus as a service and inject it into any components that need it.

I mentioned in my last post that the requirements are for the publisher and subscriber of events to know nothing about each other. A global event bus fits this bill. A global event bus, allows publish/subscribe communication between components without requiring the components to explicitly register with one another (and thus be aware of each other).

I think this will give us the quickest win for the stated requirements and we can quickly cobble together an Ember.Service that will act as an event bus using Ember.Evented:

event_bus.js
1
2
3
4
5
6
7
8
9
10
11
App.EventBus = Ember.Service.extend(Ember.Evented, {
  publish: function() {
    return this.trigger.apply(this, arguments);
  },
  subscribe: function() {
    return this.on.apply(this, arguments);
  },
  unsubscribe: function() {
    return this.off.apply(this, arguments);
  }
});

An initializer is created to inject the event bus as a singleton into anything that might use it:

initializer.js
1
2
3
4
5
6
7
8
9
10
11
12
13
Ember.Application.initializer({
  name: 'load-services',
  initialize: function(container, application) {
    var eventBus = App.EventBus.create();

    application.register('event-bus:current', eventBus, {
      instantiate: false
    });

    application.inject('component', 'EventBus', 'event-bus:current');
    application.inject('controller', 'EventBus', 'event-bus:current');
  }
});

Now a parent component can pubish events using the injected EventBus

publish.js
1
2
3
4
5
6
7
App.XPeopleComponent = Ember.Component.extend( {
  actions: {
    callChildren: function() {
      this.EventBus.publish('parentCalling');
    }
  }
});

Child components can now subscribe and unsubscribe to these events without referencing the parent component:

subscribe.js
1
2
3
4
5
6
7
8
9
10
11
12
13
App.XPersonComponent = Ember.Component.extend({
  _initialize: Ember.on('init', function(){
    this.EventBus.subscribe('parentCalling', this, 'onParentCalling');
  }),

  onParentCalling: function() {
    alert('parent called for ' + this.get('person.name'));
  },

  _teardown: Ember.on('willDestroyElement', function(){
    this.get('EventBus').unsubscribe('parentCalling');
  })
});

I think this is the quickest path to market right now as it requires little effort. Subscribing to events based on a string literal is less than ideal but this fits my purpose of being outside the bounds of data down and actions up where no data has changed and the publisher and subscriber don’t know anything about each other.

Here is a jsbin that puts it all together.

I am very open to somebody pointing out a better way.

Emberjs - Communication Between Components

Communication Between Components

A question that I see frequently asked is how can a parent component communicate with child components.

A child component can communicate with a parent in a number of ways with the most commmon at this time of writing with ember 1.11.1 is to use sendAction.

For example, a parent component can tell a child component what its primary action is or give a named action to its children:

And the child component can then call this action:

child1.js
1
2
3
4
5
6
App.XPersonComponent = Ember.Component.extend({
  actions: {
    callParent: function(person) {
      this.sendAction("action", person);
    }
  },

I have never warmed to the abstraction of callable actions existing in an actions hash and from what I can tell, it will be possible in ember 2.0 to simply pass actions around as plain old javascript functions which is something that I welcome.

In the mean time, it is possible to simulate this behaviour by creating a handlebars bound helper that returns a higher order function:

makeAction.js
1
2
3
4
5
6
7
8
9
10
11
Ember.Handlebars.registerBoundHelper('makeAction', function(){
  var actionName = arguments[0],
      args = Array.prototype.slice.call(arguments, 1, -1),
      self = this;

  args.unshift(actionName);

  return function() {
    return self.send.apply(self, args);
  };
});

A parent component can then yield this to a child component:

Here is a jsbin that shows this in action.

Parent Component calling Children

A child component calling a parent is fairly straight forward and is well laid out but what about when a parent component wants to call its children?

What do we do if we have a parent that wants its chidren to do something like to zoom to an element or something that is not a reaction to some state mutation? The official ember guidance is you should use the actions up and data down paradigm where you push data changes down to the child components but there are occasions when this does not fit. There are times when you want a child component to do something when no data has changed. You can certainly fudge this but mutating a state change to get a child component to react is pretty awful in my opinion and not something that you should do. This is an occassion when actions up and data down does not go far enough, which I have previously blogged about here and here.

So what do we do?

Subscribe to Parent Events

The first way I solved this was to use Ember.Evented. A component can mix in the Ember.Evented mixin:

people.js
1
2
3
4
5
6
7
8
9
App.XPeopleComponent = Ember.Component.extend(Ember.Evented, {
  actions: {
    callChildren: function() {
      this.trigger('parentCall');
    },

    receiveFromChild: function(person) {
      alert("received " + person.get('name'));
    }

Ember.Evented is mixed into the component and trigger is called on line 3 of the above code sample to broadcast an event to any listening children.

Below is how a child component can subscribe to these events:

child2.js
1
2
3
4
5
6
7
8
9
App.XPersonComponent = Ember.Component.extend({
  _setup: Ember.on('didInsertElement', function(){
    this.get('notifyer').on('parentCall', this, 'onParentCall');
  }),

  onParentCall: function() {
    alert('parent called with ' + this.get('person.name'));
  }
});

Line 3 subscribes to the event and supplies a handler which will be called when the parent triggers the event.

I don’t have a great big problem with this although it is not that nice having to explicitly subscribe via the parent component as opposed to just subscribing to an event.

Here is a jsbin that shows this in action.

Registration with the parent component

Another way of solving this is for the child component to register itself with the parent:

register.js
1
2
3
4
5
6
7
8
9
10
11
App.XPersonComponent = Ember.Component.extend({
  _setup: Ember.on('didInsertElement', function(){
     var parent = this.nearestOfType(App.XPeopleComponent);

     parent.registerChild(this);
  }),

  parentCalling: function() {
    alert('parent called with ' + this.get('person.name'));
  }
});

The child component finds the parent on line 3 of the above and below is the registerChild method that is used to register the child component:

parent2.js
1
2
3
4
5
6
7
App.XPeopleComponent = Ember.Component.extend( {
  children: Ember.A(),

  registerChild: function(child) {
    this.children.pushObject(child);
  }
});

I think this is less favourable because of the very tight coupling. Here is a working jsbin that shows this in action.

Register via Binding

Sam Selikoff offered this way of registering child components via a binding.

First, add a _register method to the component that executes on init:

parent3.js
1
2
3
4
5
6
App.FullscreenMapComponent = Ember.Component.extend({
  _register: function() {
    this.set('register-as', this); // register-as is a new property
  }.on('init')

});

Then, when rendering the component, supply a property to bind register-as to:

Now, the controller has a reference to the component, and can call methods directly on it:

route.js
1
2
3
4
5
6
7
8
App.PinsRoute = Em.Route.extend({
  actions: {
    focusSelectedPin: function() {
      this.controller.get('fullscreenMap').panToSelectedPin();
    }
  }

});

I think this method suffers from the same coupling as the other methods.

So what I want is a way that is less coupled. I want the publisher and the subscriber to know as little about each other as possible. I also do not want to use state mutation as a means of communication.

UPDATE: Somebody mentioned in the comments that a global event bus is anohter way of achieving what is required and I created this post that explains how to achieve this.

clojure’s core.async

I love this quote from the first sentence of this post on the clojure blog about core.async.

There comes a time in all good programs when components or subsystems must stop communicating directly with one another.

The roots of core.async go back to Hoare’s Communicating Sequential Processes (CSP).

I’ve done a good bit of hobby development with clojurescript and I love using core.async channels for communication between components. It can be used synchronously and asynchronously.

With core.async, you create channels which can be thought of as independent threads of activity (I don’t mean threads as in multi-threaded) that can be published to or subscribed to.

I have previously blogged about Handling Mouse Events With core.async.

Core.async has nailed the decoupling of publishers and subscriers via queueable channels.

Epilogue

With core.async the publisher and subscriber know nothing about each other which is really the goal of event based systems and I think both ember and react suffer from the model of handing down functions from parent to child as there is a high degree of coupling.

It would be interesting to see how ember was if we were dealing with channels as a means of communication rather than passing down callable functions.

There is a js-csp library and David Nolen wrote this post about ES6 Generators Deliver Go Style Concurrency.

Ember is going with the data down, actions up meme but there are times when this does not fit and activating state changes as a means of communication can only lead to trouble.

Emberjs - Refactoring Away From arrayComputed

Word on the emberjs street has stated that the reducedComputed familty of computed property macros are to be deprecated. I’ve used these macros in a number of places in my current contract. I also previous blogged about arrayComputed in this post.

In the example, I used arrayComputed to group the number of deals that each particular company had and supplied a total for each grouping. Here is a working jsbin that illustrates the old code. Each deal has a deal state and I group a particular company’s deals by the deal state and give it a total:

I will now begin the refactoring. The first thing I notice after changing the references in the jsbin to point to ember 1.11.0 is that the console is filled with deprecated warnings. The first warning to get rid of is:

Ember.ObjectController is deprecated, please use Ember.Controller and use `model.propertyName`

This referers to line 1 of the following gist:

And below is the ObjectController that the itemController references in the above template:

old.js
1
2
3
4
5
App.CompanyItemController = Ember.ObjectController.extend({
  dealTotals: App.computed.groupable('deals',function(deal){
     return deal.get('state');
  })
});

I believe controllers are on the condemned list and components will be the main unit of currency so the obvious thing to do is replace the itemController with a component. My updated template looks like this:

It is worth noting that the #each foo in bar syntax is also going to be depreceated in favour of the new block syntax that I mentioned in my last post and you can see how it is used on line 2 of the above. This pretty much slays most of the warning messages and I now have a component hierarchy as opposed to nested each blocks.

I have the top level company component that is rendered for each company.

Below is the x-company template:

Each company will render an x-deals component for each group of deals that are grouped by deal state. The x-deals template looks like this:

The x-deals component contains a collection of x-deal components. The x-deal component’s template looks like this:

Refactor to the infamous @each Helper

I now want to replace the arrayComputed macro I created to group the deals. Below is my original macro definition:

oldArrayComputed.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
34
35
36
37
38
39
40
41
App.computed = {};

App.computed.groupable = function(dependentKey, groupBy){
  var options = {
    initialValue: [] ,
    initialize: function(array, changeMeta, instanceMeta){
    },
    addedItem: function(array, item, changeMeta, instanceMeta){
      var key = groupBy(item);

      var group = array.findBy('key', key);

      if(!group){
        group = Ember.Object.create({key: key, count: 0});
        array.pushObject(group);
      }

      group.incrementProperty('count');

      return array;
    },
    removedItem: function(array, item, changeMeta, instanceMeta){
      var key = groupBy(key);

      var group = array.findBy('key', key);

      if(!group){
         return;
      }

      var count = group.decrementProperty('count');

      if(count === 0){
         array.removeObject(group);
      }

      return array;
    }
  };
  return Ember.arrayComputed(dependentKey, options);
};

Below is how it was used in the old itemController.

olditem.js
1
2
3
4
5
App.CompanyItemController = Ember.ObjectController.extend({
  dealTotals: App.computed.groupable('deals',function(deal){
     return deal.get('state');
  })
});

What was convenient about arrayComputed was that if any of the company’s deal’s state attributes changed then the whole property would recalculate and group accordingly. I wanted to keep this behaviour so I first of all refactored to something that has caused me problems in the past and that is to use the @each indicator. The @each indicator will observe an array for additions and removals AND also it will observe a proprety of each element in the array for changes.

I refactored the arrayComputed macro to this:

neweach.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
App.computed.groupable = function(dependentKey, eachKey,  groupBy){
  return Ember.computed(dependentKey, eachKey, function(){
    var ret = Ember.A();

    this.get(dependentKey).forEach(function(item){
      var key = groupBy(item),
          group = ret.findBy('key', key) || Ember.Object.create({key: key, count: 0, deals: Ember.A()});
      if(!ret.contains(group)) {
        ret.pushObject(group);
      }

      group.incrementProperty('count');
      group.deals.pushObject(item);
    });

    return ret;
  });
};

The above code simply returns a standard computed property on line 2 and takes a dependentKey that is the array being observed and an eachKey that will contain the @each indicator.

Below is how the x-company component that replaced the old itemController uses the refactored macro. company.deals.@each.state will observe every element of the array for changes to the state attribute.

x-c.js
1
2
3
4
5
App.XCompanyComponent = Ember.Component.extend({
  dealTotals: App.computed.groupable('company.deals.[]', 'company.deals.@each.state', function(deal){
     return deal.get('state');
  })
});

I have created this jsbin to show its usage. I’ve also updated the bin by adding a dropdown for each deal in the group that can be used to update the deal’s state and you can see things recalculate.

Data down and Actions up

I really was not happy about this refactoring, part of the job of arrayComputed was to try and nullify the performance pains and problems of @each. When I first started using ember, @each was a huge performance drain. It has improved but I really don’t know when it is going to be called by the ember runtime and when it is called is outside of my control. As I mentioned in this this post, I really want to stop using things that are outside of my control. I have absolutely no idea when or how many times this macro will be called by the ember runtime and as such, I’m not going to use it. Experience tells me that I will run into surprises and other headaches if I don’t remove it now.

I refactored the computed property macro to a plain old javascript util function:

util.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
App._ = {};

App._.groupBy = function(coll, groupBy) {
  var ret = Ember.A();

  coll.forEach(function(item){
    var key = groupBy(item),
        group = ret.findBy('key', key) || Ember.Object.create({key: key, count: 0, deals: Ember.A()});
    if(!ret.contains(group)) {
      ret.pushObject(group);
    }

    group.incrementProperty('count');
    group.deals.pushObject(item);
  });

  return ret;
};

The top level x-company component now explicity determines when the array grouping is recalculated:

recalc.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
App.XCompanyComponent = Ember.Component.extend({
  actions: {
    regroupDeals: function() {
      this.groupDeals();
    }
  },

  groupBy: function(deal){
    return deal.get('state');
    },

  groupDeals: function() {
    this.set('dealTotals', App._.groupBy(this.get('company.deals'), this.groupBy));
  },

  _setup: Ember.on('didInsertElement', function(){
    this.groupDeals();
  })
});

The didInsertElement handler on line 16 calls a groupDeals method that calls the util method. I also supply a regroupDeals action on line 4 for down level components to call this action when a deal state changes.

For example, the lowest level x-deal component will call an action when the dropdown changes:

This component bubbles the action up when the select element changes:

x-deal.js
1
2
3
4
5
6
7
App.XDealComponent = Ember.Component.extend({
  actions: {
    changeDealState: function(deal) {
      deal.set('state', this.$('select').val());
      this.sendAction();
    }
  },

This is bubbled up to the x-deals component:

x-deals.js
1
2
3
4
5
6
7
App.XDealsComponent = Ember.Component.extend({
  actions: {
    regroupDeals: function() {
      this.sendAction();
    }
  }
});

Which bubbles it up to the x-company component.

I really don’t like having to bubble things up this way but I don’t think that there is a better way available in 1.11.1 but I’m sure there will be at a future day as this is a bit tedious and coupled.

Epilogue

I much, much, much prefer my final refactoring as opposed to using the infamous @each indicator as I am in total control of when things happen. I can also introduce aynchronicity if the dataset grows and I need to call the server for the groups. It is up to me when I return the recalculated dataset.

I would take it further and use pubsub to have a reflux like data store do the recalculation as I mentioned in this post but this will at least do for now.

I think ember should remove the @each helper because people will use it because of its convenience.

I’m on the fence if I consider computed properties an evil but one thing is for sure, I do not think they are needed as often as I see them used.

I want to explicitly state when my collections/objects are available for re-rendering. I think this is the most sensible approach and things work much nicer with a top down approach.

Here is an updated jsbin with the final refactoring.

Emberjs - Passing Block Params From a Component

I have previously blogged about a hack I had to use to get the right context when using a component in its block form.

The example I gave in the post was for an autocomplete component that would give the developer the ability to prepend their own customisation to a selection. The example I gave was prepending an avatar like in the image below.

The original component could be used in its block form like this:

And here is the original component template file:

There is no way in the above to set what the context would be for the code block that is ran when the yield helper is called. The context was non-negotionable and the context would be that of the template it was declared in e.g. the controller. The only way round this was the hack that I described in the previous post.

As of ember 1.10.0, it is possible to pass internal values to a down stream scope with the new block params syntax.

I can refactor my component’s template to look like this:

  • Line 1 uses the each helper with the new block params syntax to specify a context named selection.
  • Line 4 uses the yield helper to pass the block param to the template or code block that is rendered between the component’s definition.

Below is how I can use the block param when the component is declared with a block:

  • line 2 binds the selection var that is passed to this code block via the yield helper in the previous code example.
  • line 3 puts the var to use.

Here is a jsbin with a working simpler example.