Alexander Beletsky's Development Blog

Github as blogging platform

No, I'm not going to talk about creation some github-backed blogging system. I would like to talk on some blogging style I tried to apply recently.

The problem is, technical blogging is difficult. I usually have a lot of ideas or know-how's while I create some code. It's just hard to blog about. As you didn't do the blog post during coding, you might forget some details or simply loose the encouragement to blog about it.

As I mentioned in my previous post I recently created some code that contains Backbone.js + Express.js boilerplate code that could be great start for building single page applications. I felt I need to document it somehow, so even myself will remember what's going on there. So, I put some README file there. Usually, I don't write much documentation, but during writing it I realized that it's a kind of blog post or tutorial I'm writing immediately after I created something.

I liked the way how it went. First of all, Markdown is great for technical blogging. I still use HTML and feel a but ashamed by that fact. It's so easy to format and place code examples inside with Markdown (and it looks minimalistic and great on github). Second, the content of resulted readme file, pleased me much.. I felt it's the same as blogging, but a bit.. more interesting, or so? So, I twitted about and great surprise for me, repository got 200 stars and 20 forks, got mention on JavaScript Weekly and raised some questions.

The same as blogging, but instead post you have repo with README + some valuable code. Instead comments, you got issues and pull requests.

That was really motivating experience. I think I would like to repeat it from time to time.

Building Single Pages Applications

This is transcript of talk I gave on #msswit conference 25 April 2013.


What is SPA?

If you just imagined the pools and saunas and massage rooms, this is, unfortunately, not the thing that I going to talk about. We'll check out new concept of web applications, that are called - Single Page Applications.

From technical perspective SPA means the web application, that being loaded as one HTML page and redraws it's UI without round trip to server. That sounds not so exiting, but we can see that SPA is much more than that.

GMail is canonical example of single page application. It was not the first single page application though, it became very popular and gathered a lot of users. That was probably the first time the masses of people realized new user experience - application that works in browser, behaves similar to application on desktop. So, SPA opened a of new opportunities and abilities for software developers to release and promote their applications in web, which is in common case a much easier task, comparing to desktop applications. And new approach need to be taken to create such applications.

API oriented architecture

Before we jump into SPA details, let's talk about the architecture that would allow to build apps in that way. Popularized by Twitter it's being adopted by many vendors and became kind of default. We are talking about 'API oriented' architecture.

Basically, it's just a deviation of classical 'Server-client', where we have server that provides an open API.. and where client is browser, powered by JavaScript engine.

It's quite typically that server and client are communicating through HTTP, using JSON as payload format and relying on REST principles. I'm saying typically, since it's not always the case. Some apps might takes XML and use RPC instead of REST, but that actually doesn't really matter.

Client is browser, that runs JavaScript code. JavaScript code is requesting the data and updating the DOM. Few years ago, jQuery was the primary tool of making such applications. Nowadays, we see MV* JavaScript frameworks are gaining a lot of traction and simplifying front-end development. It's not only about simplification, but also bringing the architecture principles on front-end, something that we haven't seen earlier.

How to build Single Page applications?

We have a bunch of technologies, server and client that would allow to do that. ASP.NET MVC, Web API, NancyFX, ServiceStack, Express.js, RoR.. etc, on server and Backbone.js, Knockout.js, Angular.js, Marrionette.js, Durandal.js etc. from client.

It gives a lot of options, actually. All of them have their pro/cons. I've used to use ASP.NET MVC as platform to build open API's and was quite happy with that. Nowadays, I'm using Node.js / Express.js and it works really great, as well.

The truth is, with SPA, the front-end technology plays a bit more significant role. Of course, server still performs important role for authorization, data access, business logic.. but in API oriented architecture is turns to be a kind of CRUD exposed through HTTP.

As for front-end, my experience lies in Backbone.js. Preventing the questions, I would say - Backbone.js is not perfect (as there are nothing perfect in this world). Bare Backbone.js app would require a lot of manual coding, but it would also allows to see some important implementation details that could be good for general SPA understanding.

Server architecture

Server is responsible for two principal things. First, it provides with API. Second, it server the master page (again, it's not always the case, master.html could be places in some static resource server).

Master page, is the one that being rendered in browser should bring basic DOM structure + reference the JavaScript code to initialize and run application. That's it.

As always, it's important to think about scalability. Doesn't matter what technology you pick up, it's able to scale and hanlde more incoming request with given response time is vital.

Client architecture

Scalability is important here, as well. That's a different scalability, though.

I liked the way Derick Bailey stated in one of JavaScript Jabber show:

... scalability in this case is not the number of users running the code at any given time. It’s the number of features in the system, how those features interact, and how you can start up and shut down and do all these things with these different features so that your application can grow in size, grow in features, and grow in capabilities.

That's were there the JavaScript pattern, MV* frameworks are shine. And without simple modularity, it's very hard to build scalable JavaScript applications.

Require.js and AMD

Modularity is important. Each module represents some small piece of application functionality. The problem that JavaScript (ES5, to be precise) doesn't have modules as part of language.

Require.js helps to solve the problem. Instead of referencing hundreds of JavaScript files which expose itself to global namespace, Require.js relies on, so called, Asynchronous Module Definition. The special rules which you code have to follow, to be able to act as module and being loaded by request.

Besides of that, Require.js comes with building/optimization tools, that helps to prepare application to production.

So, the Master html has a reference to Require.js main file, which will be responsible for configuration and initialization of app. This typically includes setup of view state management (ViewManager) and routing (Backbone.Router).

Routing

Router, handles in-browser URL change events and notifies about that changes.

The URL change might appear of 2 things: user clicks some href or submits the form with re-direct. The SPA prevents those things. Instead, all href click are overloaded, so instead of performing GET request on given URL, JavaScript code would let router know that URL is changing. Router receives the message and using some route rules, call corresponding handler.

The handler job is to load the application and execute it.

Applications

Applications in terms of code, are simple objects with run (or execute) function.

The responsibility of application is to fetch all required data and intitialize application Main View. The Main view is then passed to a ViewManager, which is responsible to render it and attach to DOM.

Besides of that, application is also 'logical' group of different modules with one goal. Imagine GMail application again - Contacts, Mails, Tasks are different applications. Each application, could have sub applications (with their own data and views).

The rule of thumb, one route one application.

View Manager

As it's been mentioned about, View Manager is important part of SPA architecture.

It handles the aspects of switching one application (MainView) to another. So, the content of application div is cleared up and than updated with new one. In Backbone.js application, that is particularly important, since besides the DOM update View Manager is responsible to clear up unsubscribe all events that views might be subscribed to, to prevent, so called Zombie View problem.

Main View and Subviews

Not trivial application could contain some complex UI. All complex UI is being divided on many smaller components.

MainView is responsible for whole application UI. It's typical job to instantiate and render all required subviews. It also stores the references for all subviews into some internal data structure, so it's been able to close all them, while main view is closed.

TheMailer - demo application

Here is TheMailer - very simple application that implements all the ideas above. I've created that very quickly and I could not call it completed. At the backend it runs ASP.NET MVC/WebAPI and using Require.js + Backbone.js at front end.

It allows you to view and compose email, as well as some simple management of tasks and contacts.

Under the debugger, it is clear how the application is initialized and starting up, how MainView creates Subviews and how Routing and ViewManager works.

Conclusions

I would call it SPA bare bones. As I mentioned above, using pure Backbone.js is good, since Backbone.js contains all required components which any SPA need (most important it have Backbone.Router).

But I would recommended to check further. If you plan stick to Backbone.js, Backbone.Marionette by Derick Beiley could be really nice option. For Google technologies fans, Angular.JS makes a lot of sense. For ones that liked Caliburn.Micro during WPF programming, could play with new framework Durandal.js by Rob Eisenberg.

SPA is a lot of fun and adventure, welcome in!

Building Single Page Applications with Backbone.js and Express.js

This Saturday I was doing my first Backbone.js class. It went really fine, except one fact.

I wanted to show the aspects of creating Single Pages Application running on Backbone. Started the application from scratch, we had to spend a lot of time writing some infrastructure code before we even jump to Backbone. So, after the class I decided to create some boilerplate project, so next time we would just clone it from github and start to work.

That's how the backbone-express-spa born.

Backbone.js + Express.js SPA boilerplate

The project is a Express.js application using Backbone.js as front-end framework. The idea is you just simply clone it, remove non needed routes and application and build something on your own.

I won't put to much details in a blog post, since repo neat readme section. Just several facts:

  • Minimal and simple - pure Backbone code, no plugins. For some real needs plugins are required anyway and you are free to include whatever you want.
  • AMD modules with RequireJS - modularity is key factor for large-scale apps, RequireJS
  • Concept of Application - to group all view, models, collection related to one application unit in one place.
  • Handlebars template - using Handlebars as template engine.

Further work

It's not yet completely done. I want to create more meaningful app, show some layouts principles + prepare readme section of building application for production.

I'm also thinking of putting some examples of unit tests both for Express.js and Backbone.js.

Conclusions

Check the backbone-express-spa out. If you like it, please give some stars or shout in twitter. I would be really happy to see some pull requests for improving applications or infrastructure. So, if you want to join - you are welcome!

.NET Developer in JavaScript World

This is a subscript of lighting talk I did on #odessajs conference that took place 13 April in Odessa.

The story

Thinking about the things going on inside and around me I realized - I don't do .NET development more than 1.5 years for now. It's not the first time I was thinking about that, but now it has a bit different perspective.

WTH?

I work in E-conomic company and about 2 years ago we decided to build new product.

Till that time we've learned hard few things: plain jQuery applications is mess, building new shinny product on out-dated infrastructure is bad idea.

So, we've started with front-end by choosing Backbone.js as our foundation, later on we've decided to switch our API server from .NET to Node.js.

It appears we got full JavaScript stack on that product and I involved in JavaScript more and more each day.

I thought I know JavaScript

That time I mistakenly thought, I can do JS programming. Sure, I understood jQuery selectors, concept of callback and even why we need 'var me = this;' trick in code.

But the reality was a bit different. Now, listening to podcasts and reading some blogs, I understood that I've been to 'classic' trap on C#/Java developer switching to JavaScript. Languages and frameworks requires time to learn.

Long hard way of learning

I had to spend the time to learn new stuff. I would say the best source of information was the code written by my colleagues. We have great team, so initially I were just reviewing the code following some patterns. I also spent time of peering famous OS projects like underscore and Backbone.js.

JavaScript Good Parts, opened my eyes on few important things as well.

There are 3 aspects that changed my mind on JavaScript.

JavaScript is dynamic language

Let's be clear. If someone in 2003 tell me I'm going to program dynamic language and will be happy about, I would never believe that. I was programming C++ and truly believed in types. Types as I was thinking is only way to tackle complexity of software.

Even though, I still think about some advantages of static vs. dynamic languages, my opinion has changed radically.

Dynamic languages are great. I feel I more solve problems rather than designing types (or usually hierarchy of types). Consider that, instead of thinking about the name for next "ProxyAbstractFactoryManager" I'm writing functions that do stuff.

Frictionless development

I was compiling applications for whole my life. Just to run some simple thing I need to compile and link. It's usually not a problem at all, but depends on project infrastructure it can take a lot of time. Sooner or later you start to hate builds.

With JavaScript application, you simply should run it. It starting fast so the gap between "write the line of code" and "check the results" became very small.

Instead of heavyweight IDE's I became Sublime Text 2 user. After years in VS you simply could not understand how to write code without IntellySense. But practice shows it's really possible.

Node.js

To be honest with you, I was very skeptical regarding Node.js initially. But again, practice showed different results. It's been proved that Node.js is very suitable for our product. We are running API server on Node.js and it performs really nice.

Later I started to learn what Node.js platform offers and I was really surprised with it's abilities.

CommonJS style of writing code started to make sense. Namespacing problem is solved, so you can build big applications there.

I have to add that Node.js is a significant Open Source player. Everything you get by npm is open source, you can check the sources if anything unclear. Most of Node.js modules are hosted in github, so even if you experience issues you can fix it.


Conclusions

JavaScript is awesome. I like the experience of JavaScript programming so far. Whatever you do, front-end or back-end you stay in one "language context". I would not call a huge problem, but usually context switching from one language to another can take something.

Picking up technology for next side-project or quick hack I'm selecting JavaScript.

Baby steps to Backbone.js: Exploring collections. Part 2.

Backbone.js is event-driven framework. All Backbone entities are extended from Backbone.Event object. That means, they are able to raise events, subscribers are able to listen to that events and act accordingly. Let's take a look what type of event does Backbone.Collection have.

Backbone.Collection events

Will have a test suite for that,

describe('collection events', function () {
    var listener;

    beforeEach(function () {
        collection = new FeedbackCollection();
    });

    beforeEach(function () {
        listener = jasmine.createSpy();
    });
    

Here we are creating collection for testing and Jasmine spy, special function we going to use as event subscriber.

Adding element to collection

As we saw previously there are several ways of adding new elements to collection. By add and push methods. The important thing, does not matter what API method you use, Backbone.Collection would trigger 'add' event.

By add method,

describe('while adding elements', function () {
    beforeEach(function () {
        collection.on('add', listener);
    });

    beforeEach(function () {
        collection.add({id: 'feedback-1', email: 'a@a.com', website: 'a.com', feedback: 'hello'});
    });

    it ('should raise add event', function () {
        expect(listener).toHaveBeenCalled();
    });
});
    

By push method,

describe('while pusing elements', function () {
    beforeEach(function () {
        collection.on('add', listener);
    });

    beforeEach(function () {
        collection.push({id: 'feedback-1', email: 'a@a.com', website: 'a.com', feedback: 'hello'});
    });

    it ('should raise add event', function () {
        expect(listener).toHaveBeenCalled();
    });
});
    

Each event handlers receives model itself and reference to collection.

Removing elements from collection

Similarly, there 2 ways of removing items from collection, by remove and pop methods.

By remove method,

describe('while removing items', function () {
    beforeEach(function () {
        collection.on('remove', listener);
    });

    beforeEach(function () {
        collection.add({id: 'feedback-1', email: 'a@a.com', website: 'a.com', feedback: 'hello'});
        var model = collection.get('feedback-1');
        collection.remove(model);
    });

    it ('should raise remove event', function () {
        expect(listener).toHaveBeenCalled();
    });
});
    

By pop method,

describe('while poping items', function () {
    beforeEach(function () {
        collection.on('remove', listener);
    });

    beforeEach(function () {
        collection.add({id: 'feedback-1', email: 'a@a.com', website: 'a.com', feedback: 'hello'});
        collection.pop();
    });

    it ('should raise remove event', function () {
        expect(listener).toHaveBeenCalled();
    });
});
    

Resetting and sorting

Besides just adding and removing stuff from collection, it have few more method which reaction is triggering event. It's reset and sort. Reset is the bulk insert into collection, it works great when we fetch some data from server and want to push everything just by one operation. Sort, is rarely called manually, since if collection provides comparator function, it would sort itself, during add or reset operations. But sometimes sorting could be triggered from UI as user changes the sort column of table, for example.

Resetting collection,

describe('while reseting collection', function () {
    beforeEach(function () {
        collection.on('reset', listener);
    });

    beforeEach(function () {
        collection.reset([
            {id: 'feedback-1', email: 'a@a.com', website: 'a.com', feedback: 'hello'},
            {id: 'feedback-2', email: 'b@b.com', website: 'b.com', feedback: 'good bye'}]);
    });

    it('should raise reset event', function () {
        expect(listener).toHaveBeenCalled();
    });
});

Sorting collection,

describe('while sorting collection', function () {
    beforeEach(function () {
        collection.on('sort', listener);
    });

    beforeEach(function () {
        collection.reset([
            {id: 'feedback-1', email: 'a@a.com', website: 'a.com', feedback: 'hello'},
            {id: 'feedback-2', email: 'b@b.com', website: 'b.com', feedback: 'good bye'}]);
        collection.sort();
    });

    it('should raise sort event', function () {
        expect(listener).toHaveBeenCalled();
    });
});
    

Why it matters?

Knowing the events of all Backbone.js entities is very important. You should always design you application based on events triggering/subscription, instead of direct function call. That would make your code much de-coupled and UI logic very flexible.

Likeastore, Application Built on Hackathone

It's my second time I attended hackatone. As last time, it took place in Ciklum, the best office in Kiev, so I had very strong wish to visit it. My previous experience showed several things: hacktone is absolutely unpredicable thing, you can't guess which projects will be popular or not.. and the second, that it's hard to do something valuable alone.

So, this time I decided to build a team of guys I know and trust, so we can do something together. Those two guys appeared to be my colleagues, in @debitoor project @voronianski and @mamant. We gathered together, to build a product which was called - "Likeastore"

Idea behind

All of us having at least those 3 accounts: facebook, twitter and github. And all of those are continuous stream of information. If you have an interesting network, it probably produces interesting content so you do much of likes/favorites/stars (stories, tweets, or interesting gihub repos). The problem, it's very difficult to keep this information ordered - you typically remember you heard something interesting, but could not remember the source of it.

"Likeastore" is aimed to fix this problem. Integrating wish different services it's keeping your "likes" information in good order, with nice search and smart categorizing.

likeastore login screen

What we did?

We basically allow "Likeastore" to connect all those application by their open API and collect the information from it. We transform the information into something generic and grouping it together. So, the users are having all information up-to-date in nice and clear dashboard.

Originally we had ambition to have a kinda real-time. In the way, I favorited the tweet and "Likeastore" almost immediately got the information. We had to drop it. The reason is API's of popular applications are very quoted. You simply cannot do more request that in quota, otherwise you just banned.

So, nethertheless of similar projects, we don't want to make next social network of bookmarks. Instead, we want to build easy to use and powerful information keeper. Something, that help you to have things in order.

likeastore setup screen

How we did it?

In fact, we've build a "thrown-out" prototype. The code is a shitty inside, so we bit far of nearest production. But, we've created an interesting application. We split on 2 + 1, two backend (me and @voronianski) and one front-end guy (@mamant). Sat closely and worked shoulder-to-shoulder for next 22 hours.

From the very beginning I had very clear vision of stuff we need to do. I could imagine architecture and UI principles. And as soon I shared that the teammates accepted that really fine and provided high quality feedback and collaboration. That helped us to have a strong team in my perspective.

All of us are JS developers, so no doubt we've taken a JavaScript stack as default. Node.js, powered by Express.js at the backend and Backbone.js front end. Sometimes it's tricky, but in fact - it's powerful combination.

A bit of tech info

We are having 2 main architectural units: core and connectors. Core, is Express.js application having both serving static content and providing API. The API itself, consists on public and private parts. Public part is aimed our web client (or potentiall apps), where the private is used to communicated connectors.

Connectors are just very simple HTTP services, which perform the handshake with core and then post back all data they have collected through API's. That means, we have 3 connectors now - twitter, github and facebook. Facebook, became a quite difficult to integrated with, so we currently dropped it.

We are having CouchDB as our storage. We took it, because @voronianski had some good experience with. That appeared to be a very lucky decision. CouchDB is very interesting NoSQL solution. It's storage model has few interesting features. One of them is "merge-update". Means, you can post exactly same set of information many times, but CouchDB would not create new entities. It would merge identical documents into one. That simplied connectors very much, since they no longer need to track only new information, but could post back just a transformed bulk of information from API's.

Initially, we all agreed - our UI will never be default Bootstrap theme. It's overused and impress no more as toilet door. That's where @mamant apply his best skills. He carefully worked all our screens making a it look nice and original.

likeastore dashboard screen

Presentation and feedback

Without few features we did demo-able version in time. We have concluded few major fixes, just before the deadline.

I did a presentation of app in short way, without anything unimportant (at least I wish to think so) and we had received great feedback. People liked the idea, so we've collected 32 voices that brought us 2nd place.

That gives a much of inspiration for further work! All of us are very enthusiastic to make the stuff done. It's a lot of work, actually.

I just want to say thank you to all organizers of this event, it was nicely handled. And to the team, for making it fun and interesting.

Stay tuned for release of "Likeastore", check out sources in a meanwhile.

Baby steps to Backbone.js: Exploring collections

After initial introduction to Backbone's views and models, we going to look on next Backbone.js fundamental entity - Collection. Collections represents the ordered set of models and became very handy for any type of applications. Consider that, we almost always operate with set of different models: posts, tweets, news etc. all of that are collections, typically rendered as lists or grids.

In small application we are doing through that series we have collection of feedbacks. But before I show how to integrate collection into the app, I want to make sure you understand all collection properties right. We'll do that by TDD'ing the collection and exploring it's behavior.

Collection construction

So, to create collection we need to extend Backbone.Collection object,

var FeedbackCollection = Backbone.Collection.extend({
    model: Feedback,
    url: '/feedback'
});
    

Here we just specified the URL for collection persistence and the model, of which the collection would consists of. Let's prepare the test suite for collection stories,

describe('FeedbackCollection.js spec', function () {
    var collection;
});
    

And create our first specification,

describe('when constructing', function () {
    describe('just empty', function () {
        beforeEach(function () {
            collection = new FeedbackCollection();
        });

        it('should be created', function () {
            expect(collection).toBeDefined();
        });
    });

Just to make sure, our definition is fine and we are able to instantiate new collection object.

FeedbackCollection constructor have few optional arguments - models, options. Models, could be either arrays of objects, or array of Backbone.Models. In case of object, collection constructor would "turn" them to models (taking the type we specified on collection definition) and add those models to collection.

describe('with objects', function () {
    beforeEach(function () {
        var models = [
            {email: 'a@a.com', website: 'a.com', feedback: 'hello'},
            {email: 'b@b.com', website: 'b.com', feedback: 'good bye'}
        ];
        collection = new FeedbackCollection(models);
    });

    it('should be lenght of 2', function () {
        expect(collection.length).toBe(2);
    });

    it('should contain models inside', function () {
        expect(collection.models).toBeDefined();
    });
});

or,

describe('with models', function () {
    beforeEach(function () {
        var models = [
            new Feedback({email: 'a@a.com', website: 'a.com', feedback: 'hello'}),
            new Feedback({email: 'b@b.com', website: 'b.com', feedback: 'good bye'})
        ];
        collection = new FeedbackCollection(models);
    });

    it('should be lenght of 2', function () {
        expect(collection.length).toBe(2);
    });

    it('should contain models inside', function () {
        expect(collection.models).toBeDefined();
    });
});

Both things are equivalent. Moreover, typically it's only unit tests you need to initialize collections that way, so I usually prefer first option.

The options parameter, could contain the type of model that collection contain. So, if collection does not specify model property, Backbone.Model will be created by default.

describe('with options', function () {
    beforeEach(function () {
        var models = [
            {email: 'a@a.com', website: 'a.com', feedback: 'hello'},
            {email: 'b@b.com', website: 'b.com', feedback: 'good bye'}
        ];
        collection = new Backbone.Collection(models);   // not specifying model
    });

    it('should be created', function () {
        expect(collection).toBeDefined();
    });

    it('should have models of Backbone.Model type', function () {
        expect(collection.models[0].constructor).toBe(Backbone.Model);
    });

You can override that by passing {model: MyModel} options object,

describe('while passing model option', function () {
    beforeEach(function () {
        var models = [
            {email: 'a@a.com', website: 'a.com', feedback: 'hello'},
            {email: 'b@b.com', website: 'b.com', feedback: 'good bye'}
        ];
        collection = new Backbone.Collection(models, { model: Feedback });
    });

    it('should have models of Feedback type', function () {
        expect(collection.models[0].constructor).toBe(Feedback);
    });
});

Despite of that possibility I really rare use that in practice. It's better to simply specify model type in collection definition, that makes code easy to understand.

Accessing collection elements

After collection has been constructed, it's possible to access internal models. There are several ways of doing that.

The simplest one is by index,

describe('when accessing collection elements', function () {
    var first, second, models;

    describe('by index', function () {
        beforeEach(function () {
            models = [
                {email: 'a@a.com', website: 'a.com', feedback: 'hello'},
                {email: 'b@b.com', website: 'b.com', feedback: 'good bye'}
            ];
            collection = new FeedbackCollection(models);
        });

        beforeEach(function () {
            first = collection.at(0);
            second = collection.at(1);
        });

        it('should get first model by index', function () {
            expect(first.toJSON()).toEqual(models[0]);
        });

        it('should get second model by index', function () {
            expect(second.toJSON()).toEqual(models[1]);
        });
    });

Even it possible, in real apps you probably don't know the index of model you need to get from collection, since they might come from server in unpredictable order. So, instead of index, getting by id is more appropriate way.

describe('by id', function () {
    beforeEach(function () {
        models = [
            {id: 'feedback-1', email: 'a@a.com', website: 'a.com', feedback: 'hello'},
            {id: 'feedback-2', email: 'b@b.com', website: 'b.com', feedback: 'good bye'}
        ];
        collection = new FeedbackCollection(models);
    });

    beforeEach(function () {
        first = collection.get('feedback-1');
        second = collection.get('feedback-2');
    });

    it('should get first model by id', function () {
        expect(first.toJSON()).toEqual(models[0]);
    });

    it('should get second model by id', function () {
        expect(second.toJSON()).toEqual(models[1]);
    });
});

And finally, something that I being trapped many time while starting up with Backbone - indexers on collection, does not work.

describe('indexer does not work', function () {
    beforeEach(function () {
        models = [
            {id: 'feedback-1', email: 'a@a.com', website: 'a.com', feedback: 'hello'},
            {id: 'feedback-2', email: 'b@b.com', website: 'b.com', feedback: 'good bye'}
        ];
        collection = new FeedbackCollection(models);
    });

    it('should be undefined', function () {
        expect(collection[0]).not.toBeDefined();
    });
});

Adding and removing items

Next, we need to understand to how to add and remove items from collections.

There are 2 ways of adding item into backbone collection: add, push. They are very similar, but there are difference between those. The add method takes a model or array of models and the options you can specify the position there the item should be interred to. Push method, would simply add new item to the end of collection.

describe('by add method', function () {
    beforeEach(function () {
        collection.add({id: 'feedback-1', email: 'a@a.com', website: 'a.com', feedback: 'hello'});
    });

    it('should be added', function () {
        expect(collection.get('feedback-1')).toBeDefined();
    });

    it('should be converted to model', function () {
        expect(collection.get('feedback-1').constructor).toBe(Feedback);
    });

    describe('with index specified', function () {
        beforeEach(function () {
            collection.add({id: 'feedback-2', email: 'b@b.com', website: 'b.com', feedback: 'good bye'}, {at: 0});
        });

        it('should have 2 items in collection', function () {
            expect(collection.length).toBe(2);
        });

        it('should have feedback-2 item at index 0', function () {
            expect(collection.at(0).id).toBe('feedback-2');
        });
    });
});

By push,

describe('by push method', function () {
    beforeEach(function () {
        collection.push({id: 'feedback-1', email: 'a@a.com', website: 'a.com', feedback: 'hello'});
    });

    it('should be added', function () {
        expect(collection.get('feedback-1')).toBeDefined();
    });

    it('should be converted to model', function () {
        expect(collection.get('feedback-1').constructor).toBe(Feedback);
    });

    describe('with next push', function () {
        beforeEach(function () {
            collection.push({id: 'feedback-2', email: 'b@b.com', website: 'b.com', feedback: 'good bye'});
        });

        it('should have 2 items in collection', function () {
            expect(collection.length).toBe(2);
        });

        it('should have feedback-1 item at index 0', function () {
            expect(collection.at(0).id).toBe('feedback-1');
        });
    });
});

Please note, that push recieves the same options as add, but it's just a short-cut for add method (take a look how it's implemented, to make it completely clear)

For removing the items, we also have 2 methods: remove, pop. They are opposite symmetrical to the add, push. Remove, removes specified model from collection, pop removes the last model in collection. This is shown by following specification,

describe('when removing items', function () {
    beforeEach(function () {
        collection = new FeedbackCollection();
    });

    beforeEach(function () {
        collection.push({id: 'feedback-1', email: 'a@a.com', website: 'a.com', feedback: 'hello'});
        collection.push({id: 'feedback-2', email: 'b@b.com', website: 'b.com', feedback: 'good bye'});
    });

    describe('by remove method', function () {
        beforeEach(function () {
            var model = collection.get('feedback-1');
            collection.remove(model);
        });

        it('should be removed', function () {
            expect(collection.get('feedback-1')).not.toBeDefined();
        });
    });

    describe('by pop method', function () {
        beforeEach(function () {
            collection.pop();
        });

        it('should be removed', function () {
            expect(collection.get('feedback-2')).not.toBeDefined();
        });
    });
});

Conclusions

We've just gone for a very basic features of Backbone.Collection type. Next time, we'll explore more about collections as events it produces, fetching and persisting data to server.

Third Year of E-conomic

That's my traditional post on yet another anniversary in E-conomic company. Even thought, I still work there, this year I've heard a bit less of E-conomic but more about Debitoor instead. Debitoor is very cool product me and my team is working on and I was totally focused on that during this year.

So, what's interesting about? Alright, it begins with E-conomic company, which through about 10 years on market gathered huge experience in online accounting. The primary target audience for all that years were professional accounters and administrators that have pretty solid knowledge what the accounting is. But due influence of internet economy and small-business grow there appeared high demand on simple accounting software, that could be easily understood even for non-professional accounters. That's were we saw the opportunity. That's then the Debitoor born.

Technologically it's been very innovative for us, too. As I wrote last year, the March was the month we tried how good different technologies might work for us. The decision were taking up to full JavaScript stack - node.js and MongoDB as backend, Backbone.js as front end technologies.

So, near the April we have a working product running .NET + MSSQL, that was on production and customers started to use, we decided to switch backend from .NET to Node.js. The HTTP API interfaces were "copied" from ASP.NET MVC implementation to exactly the same but on Express.js. The difference was in the way how ASP.NET MVC and Express.js is serving the HTML responses, so we have to re-desing the way how front-end application is being initialized and started. Since the low coupling of our front end to ASP.NET features, the rest of Backbone.js application remained absolutely the same.

All existing data has been exported to JSON files and been imported to MongoDB through the existing API. That gave us a chance to make some performance measuring and we definitely we happy about. Average HTTP request were handled in ~100ms that was a quite big boost comparing to previous platform.

Front-end is being involved as well. We've been switched to Single Page Application (SPA) architecture client side and there is no way back. With Node.js backend we easily moved application to cloud, all static resources to CloudFront that affected initial load time as a result made application to look and feel incredibly fast.

But the most important is - users love it! We've got plenty of sign-ups during the day, from different countries as Germany, Spain, Great Britain, Columbia etc., recently we've started premium campaign, and the premium users joins us. UI/UX are tweeked all the time, based on future application vision and A/B tests.

All that makes me feel - your work is important and you do something valuable.. and that is exactly what keeps me working on E-conomic. It's interesting and make sense - that's all I need.

Looking back to 2012

It's the first Saturday of New Year, so it would be good idea to spend some time thinking of year that passed.

Work in e-conomic

That was yet another great year in e-conomic. We have build great app - Debitoor. Along the way, we were trying different approaches, re-writing things from scratch, designing and re-designing again and again. Finally we got very solid application built upon Node.js, MongoDB and Backbone.js. Debitoor has been created with scalability in mind, we started with Heroku cloud service, eventually moved to Amazon EC for back-end and Amazon Cloud Front for front-end. Now, it's working amazingly fast and for 8 month we gathered ~20,000 signups, launched service for many countries.

At the beginning of the year we were a bunch of .NET developers diving into JavaScript. Having a very strong team of responsible professionals we've gathered initial knowledge quite fast. I've been focused almost at front-end this year. You probably noticed that I slowed down my writings about ASP.NET MVC and doing more for Backbone.js. That just reflects the fact of my current specialization. Initially, I was not very serious about Node.js platform. But with time, I became to love it. It speed up our development velocity several times, the API we've built on this platform shows amazing performance indicators.

The team has been expanded a bit. We got new very strong PO and few developers both in Ukraine and Denmark and all of those guys are awesome. I enjoy friendly and cooperative environment we have in team. Besides of that, this year we got 2 QA guys. QA influenced the development really much and helped to improve overall quality of service. I would also mention amazing UX team we have, calling themselves "UX Wizards Team" I have to admit - we are really doing magically things. UI/UX of app is changing all the time and with each iteration it became more intuitive, comprehensive and good looking.

Speaking and blogging

For 2012 and have written 63 blog posts on various topics, primarily on .NET, JavaScript and TDD. Some stats, from Google Analytics:

I don't track GA stats actively and I was really surprised to see the figures. I got 105,490 visits, 79,445 unique visits. That gives 288% more traffic than 2011. That's quite big number and I could only hope that this year the traffic would only grow up.

As for most viewed blog posts:

Something that I personally liked the most:

As I said above my focus moved from .NET to JavaScript a bit. I've started a series of blog posts called Baby steps to Backbone.js, I'm learning JavaScript and other front-end frameworks, so I would say more info about JavaScript to come.

As for speaking, I've prepared 10 presentations during 2012 and had nearly 15 speeches on different events. That's not a lot, but it's much more that 2011 and I feel good about it.

Trainings and Consulting

Our TDD in .NET training became very popular. We did a quite of the through the year. It goes very fine and thanks to XP Injection efforts I could only predict more to come. I also did a training on ASP.NET MVC which went quite fine, but very small demand could be seen on that. I hope that 2013 will bring some more trainings in JavaScript as well.

In 2012 I've tried myself as a consultant. I've been contacted by the guy who listened to my JavaScript talk and asked to help with architectural advices on new service he tries to build. I think that was very good experience for both of us. Of cause, that's just a tiny job but I hope that consulting could work for me in future.

I believe that 2012 was just the beginning of Trainings & Consulting part of my duties and 2013 will be the one to prove it.

Communities

Kyiv Beer'N'Code is something that I personally happy about. Being relauched in September 2012, we haven't missed any meet up. Taking into account it's bi-weekly meetings that's a lot. New guys, who joined the group are open minded and smart, so it's always interesting to spend time there. I would like to have say big thanks to Ciklum company, who provides a support for us.

UA Dev Club is growing and growing. Each meeting gathers more and people and it's great. I did a few talks there I try to attend as more meetings as I can (even if they are talking about Java). UA Dev Club became very active this year and I wish it only improves in 2013.

Kiev ALT.NET in opposite a little slowed down this year. Primarily, because it's leader moved to another city, so it became difficult to manage the stuff. Nevertheless, we've organized very cool meetup at the end of year with Jimmy Bogard and it motivated us to go on. We already have planned few meetings ahead and expecting more interesting foreign guests to come. Besides of that, JetBrains might be the one who can help us this year.

Side projects

The last topic in my list that makes me a bit sad. I have to admit, I haven't produced anything really noticeable through the year. My problem is that I'm starting few projects and none of them could make done. Simply lacking the energy and motivation to accomplish it. I believe that "Less is more" should be my slogan for 2013.

Some new projects appeared in my github profile in 2012:

  • Wonka - supposed to be a blogging engine based on github with easy integration to ASP.NET MVC applications. I had some designs and ideas of implementing it, but it's still in very early stage.
  • ASP.NET Mobile - small project that I've completed during preparation to the conference. It launched on AppHabor at http://aspnetmobile.apphb.com/, but the traffic is very low there.
  • FoundStyles - while my playing with Foundation framework I've decided to build small site to keep gallery of themes there, so http://foundstyles.com/ was born. I've created only 3 and after left it. But, currently it has about 300 visits per day and it make sense to update the project. It would be easier, since Foundation moved to SASS.
  • Freeze - small utility project to make a snapshots of dynamic web sites. Originally I've created it to make a snapshot of Kyiv Beer && Code site and place it to github. I've spent some time on that and it's not yet done (as well as Kyiv Beer && Code site is not moved).
  • GithubFS.net - using Github remote repository as local file system project. It's on really early development stage, but has some documentation describing ideas. And, it's not done as well.
  • Benchmark-js - tiny library for measuring JS execution time and putting that to log. Works both Node.js and browser.
  • Backbone Computed.Fields - something that I personally happy with. Started as some code I've created for debitoor it moved as stand alone Backbone.js plugin.

If you reading this and those projects looks interesting to you, so you would like to pick that up - please let me know.

Something that I has started in 2011 and feel most shame for is Candidate. Being restarted this year I had big ambitions to actually make it done. I still want to implement some meaningful product for .NET web applications deployment. And Candidate would probably be my focus at the beginning of 2013.

Conclusions

Despite of side-projects failure, 2012 was a good year. 2013 is the year of Python that means it would bring happy coding time for all the developers. Happy New Year!

Introducing Backbone.ComputedFields

Recently, I've been working on small project which I want to share here. It's called Backbone.ComputedFields and it's small plugin that extends Backbone.Model functionality a bit.

I needed to have a model with 'virtual' fields. Namely, fields that does not belong to model directly, but being computed based on some other fields values.

The easiest solution would be simply introduce some model methods, say model.getComputedField() / model.setComputedField() and store the value inside the model object. But that turns out to be bad idea, for several reasons. First, we are breaking usual Backbone interface for getting and setting values - model.get('computed') / model.set('computed', 100). Also, if model is binded to a view, we are responsible for raising events manually, in case of computed or depended field changing.

So, after few iterations Backbone.ComputedFields was born. The design goals: to be simple, to be declarative, to be friendly to model binding (read, respect the events).

Use cases

Typical use cases for Backbone.ComputedFields are: calculating the prices; concatenating several fields; encapsulating the logic of retrieving object by reference.

It's fairly important, that computed field could change. Based on it's value, dependent fields should be updated.

Examples

Let's take a look on few examples. The models here are very simplified. But, it shows the main application of Backbone.ComputedFields.

Calculating prices

The model represents the product, which contains net price and VAT rate.

var Produc = Backbone.Model.extend({
    initialize: function () {
        this.computedFields = new Backbone.ComputedFields(this);
    },

    computed: {
        grossPrice: {
            depends: ['netPrice', 'vatRate'],
            get: function (fields) {
                return fields.netPrice * (1 + fields.vatRate / 100);
            },
            set: function (value, fields) {
                fields.netPrice = value / (1 + fields.vatRate / 100);
            }
        }
    }
});

So, we have grossPrice as computed field. That field depends on 'netPrice' and 'vatRate' and being calculated by simple formulas.

var product = new Product({ netPrice: 100, vatRate: 20 });
var grossPrice = product.get('grossPrice');
    

In this case, gross price would be 120.

product.set({grossPrice: 300});
var netPrice = product.get('netPrice');

After gross price is update, netPrice will be recalculated and netPrice will be 250.

Concatenating fields

Let's have a model to represent the person with first name and last name.

var Person = Backbone.Model.extend({
    initialize: function () {
        this.computedFields = new Backbone.ComputedFields(this);
    },

    computed: {
        fullName: {
            depends: ['firstName', 'lastName'],
            get: function (fields) {
                return fields.firstName + ' ' + fields.lastName;
            }
        }
    }
});

I'm skipping the setter cause we don't need to set full name here.

var person = new Person({firstName: 'Alexander', lastName: 'Beletsky'});
var fullName = person.get('fullName');

Full name 'Alexander Beletsky' is returned here.

Referenced objects

Sometimes we have a models that only contains a reference to another model. All the time, we need to get referenced object we have to create some piece of code, which it typically copy-n-pasted thought the code base. Computed field could be a good idea to encapsulate that.

var Invoice = Backbone.Model.extend({
    initialize: function (attrs, options) {
        this.customers = options.customers;
        this.computedFields = new Backbone.ComputedFields(this);
    },

    computed: {
        customer: {
            depends: ['customerId'],
            get: function (fields) {
                return fields.customerId && this.customers.get(fields.customerId);
            },
            set: function(customer, fields) {
                fields.customerId = customer.get('id');
            }
        }
    }
});

Here we have customer field, which is computed.

var invoice = new Invoice({}, { customers: collectionOfCustomers });
var customer = invoice.get('customer');

So, I'm able to get customer model even if invoice is just holding the invoice Id.

invoice.set({customer: anotherCustomer});
var customerId = invoice.get('customerId');
    

If I'm changing the customer of invoice, the 'customerId' would be initialized with id of 'anotherCustomer'.

Conclusions

Backbone.ComputedFields is still pre-mature, but I already successfully used that in one of projects. The github page contains pretty much documentation, so you should have to problems of adopting it for personal needs.