Understanding the Ember run loop

All of the Ember.js internal code, and most of the stuff you write while creating an Ember.js app runs with the help of the run loop. It is used to batch, order and reorder jobs in a way that is optimised for efficiency. I didn’t notice it’s existence before I ran into problems with the JavaScript setTimeout function callbacks and when manually running async calls to the API.

How Ember run loop works

If you’ve read any of the productivity books out there, they all state that batching similar jobs is the key to success. Ember run loop works in a similar way. By running same or similar jobs at the same time, the browser doesn’t have to skip around from task to task, which eases the burden on it, and if you change the same property a couple of times in the same loop cycle, it will only have to process the last change.

Jobs or tasks are scheduled into different queues, and the queues are processed by priority until they are empty.

Queues

Ember run loop consists of six queues

Ember.run.queues
// => ["sync", "actions", "routerTransitions", "render", "afterRender", "destroy"]

Each one of these queues is responsible for some jobs batch that runs inside of it.

  • sync contains the binding synchronisation
  • actions is the general work queue, and the one that generally handles promises.
  • routerTranisitions contains transition jobs in the router
  • render contains the jobs that are associated with rendering the page and updating the DOM
  • afterRender runs after the DOM is complete, after all the render jobs have been executed. This is the perfect place if you want to update the DOM after it has been rendered.
  • destroy is responsible for destroying everything other objects or jobs have scheduled to destroy.

Testing

Ember run loop is really important when running tests in Ember. Ember raises errors in testing mode when we try to schedule work without the run loop.

When should you use the run loop

Strictly speaking, all non Ember api code should be wrapped inside an Ember run loop. That includes:

  • AJAX callbacks
  • DOM updates and event callbacks
  • Websocket callbacks
  • setTimeout and setInterval callbacks
  • postMessage and messageChannel event handlers

Be sure to wrap the callback body in the ember run loop and not the whole invocation. For example:

var controller = this;
socket.on('channel', function (data) {
  Ember.run(controller, function() {
    console.log(data);
    this.set(‘message’, data.message);
  });
});

This fires an Ember run loop after the callback is executed, and the callback code will be executed at exactly the right moment.

Dynamic components in Ember.js

When building Ember.js apps you will try to avoid code duplication as much as possible. One of the ways of doing that is using Ember components. Components are small, reusable pieces of code, that share a common functionality. For example, you can have a component that shows a user’s Twitter feed, that receives the twitter handle as a parameter.

Components are the new hotness and the way to go with Ember.js 2.0 and they are also being introduced and used in HTML5. Ember components are closely built to adhere to the W3C specification so they should be compatible when the component adoption increases.

Sometimes you want to render a different component in the same place, for example a user’s image and contact info, which can be different for a person and an organisation. So to avoid ugly conditionals in handlebars code there is an option to show components dynamically with the convenient component helper.

You won’t avoid having those conditionals of course, but you won’t have to put them in your handlebars templates, which should be as logic-less as possible. They can reside at the model level, as a computed property. I will simplify this even further and use an example where we will receive the value from our API.

We will be using a simple polymorphic relationship in our API and values returned from ownerType will be “user” and “company” for this example.

Of course we want to show different data for the user and the company, but because we are showing them in the same place, we would have to use a conditional in handlebars to show them. And or model (or controller) should return the isUser boolean. This approach will make future code maintenance a nightmare.

// app/models/owner.js
import DS from 'ember-data';
import Ember from 'ember';

export default DS.Model.Extend({
  name: DS.attr('string'),
  ownerType: DS.attr('string'),
  // ...
  isUser: Ember.computed.equal('ownerType', 'User'),
  // ...
});
{{#if model.isUser}}
  {{owner/user-widget owner=model}}
{{else}}
  {{owner/company-widget owner=model}}
{{/if}}

As you can see, this conditional isn’t really the best one imaginable. If we add another ownerType possibility, we will have to add an additional component (which is the only thing we should be doing), add another boolean on the Owner model, and make the conditional above even more complex than it is. No one probably wants to be remembered by code like this:

{{#if model.isUser}}
  {{owner/user-widget owner=model}}
{{else}}
  {{#if model.isOrganisation}}
    {{owner/organisation-widget owner=model}}
  {{else}}
    {{owner/company-widget owner=model}}
  {{/if}
{{/if}}

There clearly must be a better and cleaner approach. Ember component helper comes to the rescue. And with some clean coding we can avoid all of the conditionals mentioned here.

// app/models/user.js
// ... 
   widgetComponentName: Ember.computed('ownerType', function() {
     return `owner/${this.get('ownerType').toLowerCase()}-widget`;
   });
// ...

This way, the model returns a convenient and usable string when we get the displayComponentName property from it. Now we can use this and have the cleanest possible handlebars template:

{{component model.widgetComponentName owner=model}}

Component helper will resolve the correct component and render it. If a new owner type pops up, the only thing we need to change is to add the widget component for that owner, which is also a great example of separation of concerns, and we are reducing code churn a lot. To reduce the code duplication and complexity you can also take use inheritance to combine similar functionality under one object, and extend it with specific code for each object. I’ve written a blog post about it called Simple Inheritance with Ember.js that you should definitely check out.

Simple inheritance with Ember.js

When doing Object-oriented programming, we are always seeking ways to reduce the duplication in the code we write. Reusing existing code is something that every programmer wants to do most of the time. Because, we have to admit it, we are pretty lazy. But that laziness brings us great stuff like frameworks we use in our everyday jobs.

Using Ember.js and ember-cli of course, there is an easy way to remove code duplication. Ember.js has a nice way to extend every existing class, you are already programming apps in Ember that way, by extending Ember.Route, Ember.Component, Ember.Controller and a lot of other stuff in the framework.

Realising this nice thing will help us on our way of achieving maximum code reuse. Let’s say we have a component bird

// app/components/my-bird.js
import Ember from 'ember';

export default Ember.Component.extend({
  name: 'Birdie McBird',
  actions: {
    fly: function() {
      alert("I'm flying, la la");
    },
    speak: function() {
      alert('Tweet');
    }
  }
});

And we want to implement some of the same actions in the duck component, because all ducks can fly, but they just sound different, so we would do it like this:

// app/components/my-duck.js
import MyBirdComponent from 'my-bird';

export default MyBirdComponent.extend({
  name: 'Ducky McQuack',
  actions: {
    speak: function() {
      alert('Quack!');
    },
    waddle: function() {
      alert('Waddle waddle!');
    }
  }
});

Of course, we have to define our templates, and link the actions inside them, so here it goes:

<!-- app/templates/components/my-bird.hbs -->
<h2>Hello, my name is {{name}}!</h2>
<button {{action 'speak'}}>Make a sound</button>
<button {{action 'fly'}}>Fly birdie fly</button>

<!-- app/templates/components/my-duck.hbs -->
<h2>Hello, my name is {{name}}!</h2>
<button {{action 'speak'}}>Make a sound</button>
<button {{action 'fly'}}>Fly birdie fly</button>
<button {{action 'waddle'}}>Make a move, duck</button>

<!-- app/templates/application.hbs -->
{{my-bird}}
<br>
{{my-duck}}

In Ember 2.0 you will be able to reference components with the angle bracket notation, just like any other regular html tag. I’ll write about those new features sometime in the future.

If you run the example, you see that we are reusing the speak method and redefining everything else, which is great. This is a really simplified example, and done with a component. You can do the same thing with controllers, models, even routes.

I’ve made a small demo on JSFiddle so you can try for yourself. Of course, it’s a globals based Ember app, but it’s the same principle as described here. And because ember-cli is the default way of developing Ember.js apps nowadays, I’ll keep my ember posts using it.

ember-cli 101 Book Review

Ever since I first heard of Ember.js (even before the 1.0 days), I’ve been wanting to learn it. But the learning curve of the framework always veered me off from it. Also, the lack of a real project to apply Ember.js to it was also an issue. Yes, we can rebuild the Hello World (Todo MVC app) in any possible framework, but the real learning comes when you start building a real application, with all the issues and edge cases it brings with itself. Although I’ve read a lot of blog posts, watched a lot of screencasts, tinkered with it, and nothing came close to the information provided in the ember-cli 101 book by Adolfo Builes. As ember-cli is now the official “Ember Way” (not to be confused with the book that is coming out in spring/summer 2015), I’ve realised it’s worth learning about, and using it to build great applications.
A warning note, if you are looking into Ember.js, and aren’t really that proficient with JavaScript, do yourself a favour and go read this four book series first: Master Space and Time With JavaScript by Noel Rappin. It will teach you the basics of JavaScript, and it also contains an Ember.js book as the last part of the book series.
In the book, the author guides us through creating a simple item borrowing app. The difference from all other tutorials is that the author has created the backend API for us and has different endpoints, as he guides us through the book. You will learn how to implement a medium complexity app with a REST (Rails active_model_serializers) API. Also, you will touch all of the Ember.js components, and implement them in your demo application. You will also get to learn the awesome ember-cli cli generators, which are a really nice thing, especially looking from a perspective of a Ruby/Rails developer, that is used to having those nice things.
Although I’ve learned a lot from this book, I still have to reference the Ember.js API docs for every complex issue. As I will probably have another blog post on learning things, I won’t write much of it now, but the gist is, you have to build 10 apps to be a specialist in a framework, or one or two really nasty ones. You will encounter basic issues when you are starting out, and some weird ones specific only to your project. But that is the thrill of our job, and we need to embrace it, it wouldn’t be much fun writing todo apps our whole lives, would it?
Back to the book, it’s a fairly light read, updates constantly, and as the author himself promised, it will be updated at least until Ember.js version 2.0, which is still in the RFC process. If you are thinking about learning Ember.js, you should definitely consider reading it. You won’t learn everything, it isn’t a silver bullet book that will teach you a new framework in an afternoon, but it will give you a much better start, compared to everything else that is out there. Also, consider that Ember.js is constantly improving(with a 6-week release cycle), so having an up to date resource, while you are learning the framework is a great thing.

Select and de-select all checkboxes using jQuery

On almost every application I’ve worked on, there was a similar user story:
When i visit the page showing the list of unpaid/unprocessed things, I want to be able to select some of them to process automatically.

The best way to do this is with checkboxes, and a simple form that will submit to a given path, collecting the items you need to process.

Basically the next user story after that one is: I want to be able to select all checkboxes, so I don’t have to click each one if there are plenty of them.
This is where the story would get complicated, but it is really easy to do.
Let’s say that you have a check_box with an id of #select-all-checkboxes and that your form contains checkboxes with a class of .selectable-checkbox like this:

<input id="select-all-checkboxes" type='checkbox' value=1/>

<form action="/action" method="post">
  <input class='.selectable-checkbox' name='checkbox_name&#91;&#93;' type='checkbox' value='1'/>
  <input class='.selectable-checkbox' name='checkbox_name&#91;&#93;' type='checkbox' value='2'/>
</form>

The solution to toggle them all is very easy, with JavaScript:

$('#select-all-checkboxes').change(function() {
  var is_checked = this.checked;
  $('.selectable-checkbox').each(function() {
    this.checked = is_checked;
  });
});

or with CoffeeScript:

$('input#select-all-checkboxes').change ->
  is_checked = @.checked
  $('.selectable-checkbox').each ->
    @.checked = is_checked
    return

And that is about it, now you have select/de-select all checkboxes working on your site. Be sure to wrap the above code in a $(document).ready(function() {}); or some other initialiser that is fit for your application.

Dynamically moving div with jQuery

Surely there has been a instance when you are creating an application that
has a sidebar and a main content div. In the case of content being too long,
the useful sidebar info can get left behind when you scroll down to see the other content.

In that case, you need to have some solution to scroll the sidebar content
down as the user scrolls down. You can go with something like:

.movable-div {
  position: fixed:
}

And that will work, if the sidebar content is fixed to the top of the page. If
not, you need something to know when to stick the content to the top of the
page and when to unstick it, as the users srolls up.

Think of Yelp search page, and their map that smartly sticks to the top of the
page when you scroll. So you need to use some JavaScript to achieve that. I
chose jQuery for that job and wrote a simple helper to achieve that.


// we need to fix the distance from our div to the browser top
var baseTop = $(“div#sticky”).offset().top;
$(window).scroll(function () {
var top = $(window).scrollTop();
if (top >= baseTop) {
$(“div#sticky”).css({
“position”: “fixed”,
“top”: “2px”
});
} else if (top < baseTop) { $("div#sticky").css({ "position": "", "top": "" }); } }); [/javascript] For this to work, your #sticky div must be nested inside another one in the sidebar, let’s call it #sidebar so it wont pop out to the left while you scroll down. I’ve made a jsfiddle so you can take
a look at it in action. I’m really no front-end guy so please don’t take my
div coloring skills against me.

Resources:
Sticky div jsfiddle

Integrating turbolinks in your Rails application

We are all excited in a new addition to rails plugins family that is turbolinks.

If you have tried to include it in your application, you may have noticed that turbolinks doesn’t trigger your $.ready, because there is no full page reload. As a consequence your javascripts that are bound to $.ready won’t trigger. I will only hack the finished event that is “page:change” which occurs when the page is refreshed. You have other events and their descriptions on the turbolinks github page. Here is a fast hack that i came with. Some of the code is taken from turbolinks library.

First have your $.ready trigger the “page:change” event. This is done, so we can bind everything that is now bound to document.ready to “page:change”

$.ready ->
  triggerEvent "page:change"

triggerEvent = (name) ->
  event = document.createEvent 'Events'
  event.initEvent name, true, true
  document.dispatchEvent event

Now when we have $.ready calling “page:change” we can use it in our application like this

document.addEventListener "page:change", ->
  alert "I am called from $.ready and page:change"

Will Paginate in Rails using remote request

Have you ever wondered why is there no remote option for will_paginate gem? It’s too complex and data dependent to handle all possible situations. I have made a workaround that can help you implement simple ajax pagination for your rails application. I will be replacing the whole yield part here, but you can customize it whatever way you like.

Step 1. Extract your required view into a partial so you have
index.html.erb

<!-- app/views/posts/index.html.erb -->
< %= render "index" %>

_index.html.erb

<!-- app/views/posts/_index.html.erb -->
<h1>Listing posts</h1>
<table id="posts">
  <tr>
    <th>Title</th>
    <th>Body</th>
    <th></th>
    <th></th>
    <th></th>
  </tr>
 < %= render partial: 'post', collection: @posts %>
</table>
< %= will_paginate @posts, remote: true %>
<br />
< %= link_to 'New Post', new_post_path, remote: true %>

Note the remote: true part of the will_paginate call, we will bind the javascript to it in an instance.

2. Add a div surrounding your yield tag in your layout

<!-- app/views/layouts/application.html.erb -->
<div id="content>
  < %= yield %>
</div>

3. Create index.js.erb which will replace the contents of the div with paged table data.

// app/views/posts/index.js.erb
$("div#content").html('< %= escape_javascript(render "index") %>');

4. Bind the will_paginate link click to the rails remote call using coffeescript in

# app/assets/javascripts/posts.js.coffee
$('.pagination[remote=true] a').live 'click', ->
  window.history.pushState(null, 'hi', $(this).attr("href"))
  $.rails.handleRemote($(this))
  return false

We also change the address in the navigation bar with PushState, because it can happen someone will press F5 or something and reload with a different params[:page].

Update: As my coworker Oliver mentioned, i forgot to include responding to js in our controller for the index action

def index
  @posts = Post.paginate(per_page: 8, page: params[:page]
  respond_to do |format|
    format.html
    format.js
  end
end

Preventing users from exiting a form on your website with JQuery

I have encountered a problem with users on a webapp that i co-created. The users would click back after entering data in a form, or close the current tab or something. They were so used to client-server workflow, with open connections to the database that prevented that kind of actions. So i got handed the assignment to prevent the users from doing almost anything but submitting on a data entry form without a notice.

It seemed as a hell of a solution, but i managed to make a simple plugin that works on all major browsers, except Opera. Using window.onbeforeunload, we can prevent the user from doing anything that would hurt their unsaved data. you just load the javascript file, put a tag into your forms that you want to protect and it works out of the box with JQuery.

var isSubmitted = false;
window.onbeforeunload = function() {
  var message = "You could have unsaved changes!";
  if ($('form[data-validate-exit="true"]').length > 0)
  {
    if (!isSubmitted)
    {
      return message;
    }
  }
}
document.ready = function() {
  $('form[data-validate-exit="true"]').find('button[type="submit"]').click(function() {
    window.isSubmitted = true;
  });
}

The message doesn’t show on firefox, but a convenient one will show, enough to warn the user on his actions.

The html code in your form should be like this:


<form data-validate-exit="true">

Your html here

</form>

One friendly suggestion if you follow this path, after you implement this on any of your web apps, use Opera for development, or comment the stuff out for your own sake, you will loose your mind clicking on the leave validations.