Google+

AngularJs vs EmberJs - A Comparison

So you want to build a single page web application (SPA), and you want to pick a framework to do it with. There are plethora of them out there - TodoMVC lists 15 "pure Javascript" implementations, and a total of over 60 MV* frameworks. How do you confidently pick from them all?

Most would start by reading blog posts and various reviews online, but that only gets you so far, as the majority of them are written by someone who belongs to one camp or the other, and quite often roots very strongly for their chosen framework. It was quite hard to find any objective opinions.

The Book

Faced with this task myself, I began to collect opinions from both sides, and filter out the vitriol. More importantly, I tried out and built prototype applications with them. In light of time, I only did this for two frameworks: AngularJs and EmberJs.

I have assembled what I have learned into a short book, which you can read online, or read as an ebook.

AngularJs vs EmberJs on Leanpub

Do you actually need a SPA?

The first thing you will need to do is decide whether you really need an MVC framework. This boils down to two questions:

  • Do you want "single page", or do you want "application"?
  • Do you want a presentation layer, or do you want the full structure of models, views, and controllers?

If what you are building can be more accurately described as an app than a website, then sure, a SPA framework such as AngularJs or EmberJs is apt. Otherwise, it is probably overkill. For example while you can use AngularJs/EmberJs to create a blog, you are probably better off with a simpler framework or library.

If you wish for Javascript to mostly just do the presentation logic - views and templating - you are probably better off with a framework like Famo.us or ReactJs, as they focus on that exclusively.

Which SPA is best?

Looking online on this topic, most posts fit one of these two categories:

  • Framework X is the best framework because it has these features
  • Framework Y is the lousiest framework because it has these problems

The latter type is even even less helpful when they focus on edge cases, which you are bound to run into in any framework.

Reading these articles might give you some perspective on each framework, but what is lacking is detailed a side-by-side comparison of the parts of each framework. This is precisely what my book does.

However, in this post, we will skip that, and get into the guts of how to make that decision right away. The implied premise of this is that there is no best framework, but there most certainly is a best framework for your particular app.

Here are some questions you may want to mull over when picking a framework.

1. What do you like or dislike about the syntax?

Most of the time, you will be writing code. Therefore syntax matters a lot. Examine the sample code for a router, a model, a view, a controller, and a component. Can you see yourself writing in this style, and do you have a preference for one style over the other?

I feel that it is important to familiarise yourself with what the code looks like before picking a framework, not only because you will be writing it, but also because it gives you a glimpse into higher order functionality from the get go.

For example, you might look at AngularJs' router definition syntax and compare it to EmberJs' router definition syntax; and infer that in AngularJs all routes are flat, whereas in EmberJs routes can be hierarchical. Some further research might indicate that hierarchical routes are indeed possible in AngularJs, but a 3rd party library, ui-router is necessary.

Another example might be that you compare AngularJs' component definition syntax, using directives with restrict, transclude, and isolate scope, to EmberJs' component definition syntax using Ember.Component.

For each of these examples, you can think about it in the context of the app that you plan to build. Perhaps you already know whether your app will need hierarchical routes. Perhaps you already know whether a standard component will do, or if you need a higher degree of flexibility when defining components.

All these sorts of things can, and will cross your mind, simply by familiarising yourself with the syntax when writing code using each framework.

2. What kind of learning curve do you want?

  • If you prefer an easy learning curve up front, and do not mind a steep learning curve later on, then AngularJs
  • If you prefer a steep learning curve up front, then EmberJs

This, of course, does not apply to every one. If you have prior experience with Ruby on Rails, then the learning curve for EmberJs is likely to not be as steep up front. If you have prior experience with Java, then concepts such as dependency injection in AngularJs are going to be familiar.

This is true, not just because of familiarity or similarity in code, but also because of the history and philosophy of the authors, and what they were inspired by when they created the frameworks.

One other thing that you should do, is to check out the documentation for each of the projects. Survey them for their quality: How easy it is to find information about something, and how complete the documentation is. My opinion is that both of them have rather solid documentation - at least they do now - but many others have complained about their shortcomings, so make up your own mind when you take a look.

3. What else do you need to learn or use to become proficient?

In addition to the framework itself, you will also need to learn how to use other libraries or tools, in order to develop your app. You do not necessarily need to use any of these, as both frameworks can be used in their own right. However, in practice, when developing a serious app, this is what most developers use. It is, therefore, a good idea to know what these are ahead of time, before jumping into one or the other.

With AngularJs, you will most likely need to learn:

  • ui-router (an alternative, more power router)
  • gulp or grunt (build tools)

With EmberJs, you will most likely need to learn:

  • ember-cli (a command line utility used to scaffold and build EmberJs apps)
  • broccoli (a build tool)
  • jQuery
  • ember-data (for models and persistence, distributed separately from the main EmberJs)

It is evident that for EmberJs, there is much more to learn to use in addition to the framework itself. With ember-cli however, the flip side of learning one additional tool, is that it makes app development a lot more productive, by allowing you to scaffold part of the app quickly. Therefore there are pros and cons to weigh for each.

3. How complex is your app?

  • Creating simple apps is easier to do with AngularJs than it is to do with EmberJs.
  • Conversely, creating complex apps is easier to do with EmberJs than it is to do with AngularJs.

This stems from something that occurs under the hood in each framework, that you most likely will not encounter when beginning with either framework.

Both frameworks are able to update their views when their models change, and update their models when their views change. This is two-way binding. However, both of them use different means to listen for changes on models. Until Object.observe() lands in the next version of ECMAScript, it is not possible to listen for changes on Javascript objects.

Ember solves this by requiring all models to be wrapped in Ember.Object, and use accessors (get and set) to view and manipulate those properties, attaching the event listeners to the accessor methods. AngularJs allows you to use regular Javascript objects as models, but it keeps a copy of every model, and checks for differences at a regular interval (within its digest cycle) between the model, and the previous copy of it.

EmberJs' approach results in more verbose syntax when manipulating models, but performance does not take a hit as models become more numerous or complex. AngularJs' approach has nicer syntax when manipulating models, but performance takes a hit as models become more numerous and complex.

The problem with AngularJs described above is mitigable, however, it is not easy to do so correctly, as it requires some very in-depth understanding of how the internals of AngularJs work. Thus, when picking a framework, it would be pertinent to lay out the wire frames for each of the screens in the app, and estimate the size and complexity of the models required to be displayed on each screen. If your models exceed 2000 pieces of information (this is only rough number, from Misko Hevery), your choices are:

  • Either choose EmberJs, or
  • become familiar with advanced dirty-checking avoidance techniques in AngularJs.

I have previously written in detail about accessors vs dirty checking.

4. Do you agree with the philosophy of the framework?

This is quite a fundamental question, and yet, largely a matter of personal preference.

AngularJs is an extremely flexible, and unopinionated framework. Take, for example, that it provides six different ways to define a service on a module (one of which is confusingly named "Service"). This, and many other instances of an abundance of choice, means that there are many different ways to accomplish the same task, and thus developers tend to go about doing things in different ways.

EmberJs, on the other hand, is a stark contrast to this, in that it is extremely opinionated. In most things, EmberJs explicitly defines the one correct way to do something, and everything else that you try simply will not work properly. A great example of this is the naming conventions imposed by the framework - if you name your controllers something other than what is expected, the controller is simply ignored! While this is a major stumbling block when first starting out with EmberJs, it also ensures that most developers stick to doing things in the one prescribed way.

This boils down to the level of abstraction. Those who prefer AngularJs tend to be those who prefer a lower-level framework, as it affords them more flexibility, and is closer to the metal. Those who prefer EmberJs tend to be those who prefer a higher-level framework, as they prefer the consistency and ease of collaboration that comes with a lack of flexibility.

5. Do you like where the framework is heading?

Both AngularJs and EmberJs are in their 1.x versions. Their authors have recently released their vision for their 2.0 versions.

In summary, EmberJs looks like it is going to be quite stable in its transition from 1.x to 2.0, with very few breaking changes. AngularJs, on the other hand looks like it is going to be a complete rewrite, and the transition going from 1.x to 2.0 is going to be a painful one for most developers, with many breaking changes.

Round up

So which should you pick? Answer the questions above, and you will know which on you prefer. If you are still undecided, select one or two screens from your app, and develop them using both frameworks, keeping these questions in mind, and then decide!

Functional Javascript for Social Good (and Fun)!

This post will take you through, in about fifteen minutes, a beginner's crash course in Javascript, and apply it to a very worthwhile cause. You might even make some money by doing it!

The Objective

Kiva is an organisation that enables anyone to participate as microcredit lenders.

You could get started with Kiva by using their search function; alternatively, you could also get started by using Kiva's API plus some Javascript.

The objective is to be able to perform a query on Kiva's data to select one or more of Kiva's partners, to make micro-credit loans to. By making loans to these organisations, you are helping to improve the lives of some of the most poor people in the world, and therefore doing some social good.

You might ask, why it is important to be selective of the partner organisations that you make loans to. These loans come with a high risk - primarily because the borrowers do not have to put up any collateral as security for the loans; because they quite often do not have much by way of collateral to begin with! This means that if they default on their repayments, there is no recourse, and the loaned amount needs to be written off as a loss. The good thing is that some of Kiva's partners have a better track record than others when it comes to managing micro-credit loans effectively. As a lender, it is in your best interest to pick the more reputable partner organisations.

Getting started

Fire up Chrome. (If you do not use Chrome, you can still work through this, but the instructions could be slightly different - YMMV) Next, open developer tools - hit Ctrl+Shift+C. You should see a new pane open up, with various sub-panes.

The pane we are most interested in for this exercise, is "Console". The console gives you access to a REPL (Read-Evaluate-Print-Loop). Many web developers use this to find out why the web sites that they build are misbehaving. We, however, will not be building any websites, and will simply be using this to execute Javascript code.

Loading data

Visit http://api.kivaws.org/v1/partners.json.

When you visit that URL, Chrome quickly realises that is not a web page, that you are visiting, but actually JSON. JSON is a text-based data exchange format which is very common on the web, because it can be read and manipulated easily using Javascript, which is exactly what we will be doing!

Chrome does not display JSON though, only web pages, so it puts the JSON into a minimal web page. Unfortunately, this does not work in our favour, as we will need to extract the JSON back out from the web page. So go to the console, and enter the following two lines of code:

var txt = document.querySelector('pre').innerHTML;
var json = JSON.parse(txt);

The first line finds where Chrome has put the JSON into the web page, and extracts it, putting it into a variable named txt.

The second line then takes txt, which is presently just a string of text characters, and parses it as JSON, storing it in another variable, this time named json.

Objects and Arrays

We have successfully used the Developer Tools Console as a Javascript REPL, and created a JSON object.

Let us inspect the object to see what it contains. To do this, simply enter json into the console, and Chrome prints out a summary of the object.

json;
> Object {paging: Object, partners: Array[341]}

This means that the json object contains two child properties, paging, and partners. We do not care about paging, but we do want to inspect partners. To query a property of an object we use dot-notation... in this case json dot partners:

json.partners;
> Array[341]

This partners array contains information about all of the Kiva partners. This is not very helpful though, as none of us have the time to look through over 300 items.

Let us just look at the very first partner. To query an element of an array, we use square bracket notation... in this case json.partners open square bracket 0 close square bracket.

json.partners[0]
> Object {id: 1, name: "East Africa Beta", status: "closed", rating: "0.0", due_diligence_type: "Full"…}

Note that the index of the first element of the array is zero. Arrays in most programming languages, Javascript included, start at zero, not one. Similarly, the last index of the array is its length minus one:

json.partners.length
> 341
json.partners[340]
> Object {id: 417, name: "Emerging Cooking Solutions Zambia ltd", status: "active", rating: "Not Rated", due_diligence_type: "Experimental"…}

In the first command, we use dot notation to query the length property of json.partners. In the second command, we use square bracket notation to query the last element of the json.partners.

The more astute might have noticed that we were able to use dot notation to query a property on an array, and perhaps got a little confused. That is because, in Javascript, all arrays are objects too! (not all objects are arrays though).

Functions and Functional Programming

Now it is time to level up to functional programming. We are not going to be doing the full deal here, and indeed there are other languages much better than Javascript for functional programming. Javascript does, however, support parts of the functional programming paradigm that we are interested in, which are the functions that operate on arrays.

This is, however, available only on modern browsers, that implement the newest version of the Javascript specification (ES6). Test that your browser is good enough by entering the following command:

Array.prototype.filter
> function filter() { [native code] }

If your output is different, for example, if it is null or undefined, then you will need to get a better browser, or make sure you have updated to the latest version.

Once you are done, we shall get cracking with filter, sort, and map.

If you are curious what the prototype property is, you will need to do some reading on your own - it is a more advanced concept, and we will not be covering that concept here.

The only thing that we are concerned with, about prototypes, is that Array.prototype provisions all Javascript arrays with a number of functions, including filter, sort, and map.

Filter

The first thing that we want to do is make sure that we find partners that are active. Inactive partners on Kiva do not have any active fund raisers for you to contribute to.

All arrays have a filter property that is made available to them through the Array prototype. This function takes in three parameters - but we only care about the first one.

What happens when filter is called is:

  • takes the original array, and loops over each of its elements, from first to last
  • for each of the elements, it calls the function, with the element as the first parameter
    • in this case, we call the element partner
  • if the return value is true, that element is added to the output array; otherwise it is discarded
  • the value of the output array, is therefore, always a subset of the original array
var outputArray = originalArray.filter(function(element) {
    return true /* or false */ ;
});

Now let us decide which properties we wish to filter upon, so let us just inspect the first partner on the full list:

json.partners[0]
> Object {id: 1, name: "East Africa Beta", status: "closed", rating: "0.0", due_diligence_type: "Full"…}

In Chrome, if you click on the small triangle next to the output, the object will expand to show all of its properties. This one happens to have a property of status set to closed. We do not want that, we only want partners whose status is set to active. Without any filters, we have 341 partners.

json.partners;
> Array[341]

Next we add a filter so that only active partners are included, and now we are down to 253 partners:

json.partners.filter(function(partner) {
    return partner.status === 'active';
});
> Array[253]

That list is still too big, so let us narrow it down further.

We inspect the first object by repeating the previous query and adding [0] to the end.

json.partners.filter(function(partner) {
    return partner.status === 'active';
})[0];
> Object {id: 9, name: "KREDIT Ltd.", status: "active", rating: "4.5", due_diligence_type: "Full"…}

Expand the object, and we now see a new property, which was not present on the closed partner we looked at earlier - profitability. Let us add a filter for that too.

Now we wish to return true based on satisfying two conditions. The way to do this is using the Boolean AND operator, which is represented using && in Javascript. Here we add a second condition, that a partner's profitability must be at least 0.1%:

json.partners.filter(function(partner) {
    return partner.status === 'active' &&
        partner.profitability > 0.1;
});
> Array[110]

Now let us inspect the first element in the array output above. There is one more property that we want to filter partners on, the rating that Kiva assigns to each of them, we only want partners who are rated more than 3.5 stars out of 5 stars.

Following the steps above, we might be tempted to do the following:

json.partners.filter(function(partner) {
    return partner.status === 'active' &&
        partner.profitability > 0.1 &&
        partner.rating > 3.5;
});

However, this can lead to incorrect results, as the JSON returned by Kiva returns the value of rating as a string (text) instead of a number. Thus, we need to convert it to a number first. In Javascript, we do this using parseFloat:

json.partners.filter(function(partner) {
    return partner.status === 'active' &&
        partner.profitability > 0.1 &&
        parseFloat(partner.rating, 10) > 3.5;
});
> Array[24]

Based on our filters alone, we have narrowed down our total number of partners from 341 to just 24!

Documentation for Array.prototype.filter()

Sort

Once you have grokked filter, sort should come pretty easily.

What happens when filter is called is:

  • takes the original array, and loops over each of its elements in an order determined by the sorting algorithm
  • as it does so, the algorithm will need to determine for each pair of elements, which comes before the other
  • for each pair of elements, it calls the function, with a pair of elements as its first and second parameter
    • in this case, we call the elements p1 and p2
  • if the return value is less than zero p1 is sorted closer toward the first element of the array than p2
  • the output array always contains the same elements as the input array, but usually in a different order
var outputArray = inputArray.sort() {function(element1, element2) {
    return 0 /* or any other number computed by comparing element1 to element2 */ ;
}};

Applying this to our Kiva dataset, we do:

json.partners.filter(function(partner) {
    return partner.status === 'active' && partner.profitability > 0.1 && parseFloat(partner.rating, 10) > 3.5;
}).sort(function(p1, p2) {
    return p2.profitability - p1.profitability;
});
> Array[24]

By subtracting the profitability of the second partner from the first partner another, we always get a negative number when the first partner's profitability is higher, therefore sorting the array in decreasing order of profitability.

Documentation for Array.prototype.sort()

Filter again

Now that we have sorted the partners in decreasing order of profitability, we can perform another filter, because we are only interested in the top ten amongst them.

The only thing that is different this time around, is that we now ignore the first parameter in the function, and only care about the second parameter that is passed in. The second parameter is the index of the element within the array. Since the array is already sorted by profitability, to get the top ten, we simply have to select the partners whose indices are zero through nine:

json.partners.filter(function(partner) {
    return partner.status === 'active' && partner.profitability > 0.1 && parseFloat(partner.rating, 10) > 3.5;
}).sort(function(p1, p2) {
    return p2.profitability - p1.profitability;
}).filter(function(partner, idx) {
    return idx < 10;
});
> Array[10]

In fact, this was the motivation for sorting the array in the previous step. I was a little sneaky by leaving that out until now, but it is a lot easier to explain now!

Map

Now we have narrowed it down to just ten partners, and we can inspect the output array in Chrome - it is almost ready to use!

However, there is just one last step. Let us make it a little bit easier to use the output. Reading that data within the context of a JSON object has a high geek factor, but it is not really that useful, is it?

Now that we have a filtered list, why not go to the web page for each of these partners?

Go to the main Kiva site, and browse to any partner's page, then look at the URL in the address bar.

e.g. http://www.kiva.org/partners/99

Eyeballing this URL, an educated guess would be that the URL for a partner is "http://www.kiva.org/partners/" followed by the partner's ID.

To confirm this, open the first element from the output of the "Filter Again" step above, and copy the its id attribute, and paste it into the address bar, replacing the existing ID that was there. The new partner page loads, and the partner name, and all the other information matches. Success!

Now let us use this information to construct the URLs for each of the Kiva partners.

After grokking filter and sort, map should come pretty easily.

  • takes the original array, and loops over each of its elements, from first to last
  • for each of the elements, it calls the function, with the element as the first parameter
    • in this case, we call the element partner
  • whatever the value the function returns will be added to the output array
  • the value of the output array, is therefore, always a transformation of the input array
var outputArray = inputArray.sort() {function(element) {
    return element /* or any thing you compute from element */ ;
}};

Applying this to our Kiva dataset, we do:

json.partners.filter(function(partner) {
    return partner.status === 'active' && partner.profitability > 0.1 && parseFloat(partner.rating, 10) > 3.5;
}).sort(function(p1, p2) {
    return p2.profitability - p1.profitability;
}).filter(function(partner, idx) {
    return idx < 10;
}).map(function(partner) {
    return 'http://www.kiva.org/partners/'+partner.id;
});
> Array[10]

If you click on the triangle next to the output array, Chrome expands it, and since it recognises the strings as URLs, it turns them int links, making it easy for you to click on them.

Documentation for Array.prototype.map()

Mixing it up

Let us say that you have a different set of criteria:

  • We do not care about the profitability of a partner
  • We require a higher Kiva rating of the partner, and require Kiva to have done a full due diligence check on them
  • We want to sort them in order of their default rate

We can then use the same structure as we had earlier, but modify the criteria within the first filter function, and the sort function.

json.partners.filter(function(partner) {
    return partner.status === 'active' &&
        partner.due_diligence_type === "Full" &&
        parseFloat(partner.rating, 10) > 4.0;
}).sort(function(p1, p2) {
    return p1.default_rate - p2.default_rate;
}).filter(function(partner, idx) {
    return idx < 10;
}).map(function(partner) {
    return 'http://www.kiva.org/partners/'+partner.id;
});

The second filter function is not really necessary any more, as the total number of partners that match the more stringent criteria is now less than ten anyway.

We keep the map function as it is, because we are still extracting the URL.

Now we a have a completely different set of Kiva partners than we did using the previous selection method.

Write down your own criteria in selecting partners, and then write some Javascript code to run it.

If you are having trouble, leave a comment below this post. Alternatively, if you have written some code for selecting a Kiva partner that you would like to show others, leave a comment too!

Now, donate!

It is all fine and dandy to learn some new Javascript tricks, but up until now it is merely an academic exercise.

If you wish to make some real world impact, and do some social good, open up each of the partner URLs that you now have in your output, and browse the loan recipients that are with this partner.

While I think it makes to write code to select the Kiva partners you prefer, I do not think it makes sense to do the same when selecting individuals or groups to make micro-credit loans to. My rationale is simple: It makes the most sense to select Kiva partners based on quantitative metrics, which code is good at analysing and comparing; and it makes the most sense to select Kiva partners based on qualitative metrics, which is better done by a human brain than through code.

For example, when I looked through all of the potential recipients of micro-credit loans through each of the Kiva partners that I had selected, I was not selecting them based on easily quantifiable metrics such as their gender,their age, or even how close they were to reachign their funding target.

Instead I selected them based on their story; what they were planning to do with their loan if they received it. I was looking out specifically for those who had an entrepreneurial spark of some sort, such as the a guy who wanted to purchase an amplifier for his live music performances. I was also looking out for personal qualities that indicate they were likely to succeed in their endeavour, such as the girl who had already started one business and was looking to start a second one.

Q & A

Q: Can't I just use the "Advanced Search" function?

A: Why, yes, of course you can - but that would not have been half as fun!

Q: I seems counter-intuitive to make API requests in a browser's developer console. Why not just use curl/ wget/ NodeJs/ Python, et cetera?

A: Sure, you can use all of those. You are an experienced software developer, you can use whatever tool you feel fit! This tutorial was intended for absolute beginners, and thus expressly avoided the need to install any tools. It is safe to assume that almost everyone reading this has access to a web browser!

Q: Does it matter what order I perform the sort, filter, and map in?

A: Yes and no, but most of the time, yes it does matter. In this example, if you crop filter for the first ten elements, before you perform the sort, you most certainly are not going to get the top ten. Similarly, if you map before anything else, the results will be incorrect, because the functions expect provider objects, not strings.

Building RESTful API server in Rust with nickel-postgres

Following on from my first Rust program, I have created my first Rust library, nickel-postgres.

nickel-postgres on Github

You can use it in your projects by adding this to Cargo.toml:

[dependencies.nickel_postgres]

git = "https://github.com/bguiz/nickel-postgres.git"
rev = "feature/init"

Here is a sample webserver that demonstrates how to create a RESTful API using Nickel.rs and nickel-postgres, and includes a demo front end to test it out.

Here is how - First off, import the crate and middlware class:

extern crate nickel_postgres;
use nickel_postgres::PostgresMiddleware;

Next, add instantiate PostgresMiddleware, and add it to your instance of Nickel:

let mut server = Nickel::new();
let postgres_middleware: PostgresMiddleware = PostgresMiddleware::new(
    "postgres://postgres:postgres@localhost", postgres::NoSsl, 5);
server.utilize(postgres_middleware);

Finally, within each HTTP request handler functions, obtain a database connection:

fn a_handler_function(req: &Request, response: &mut Respose) {
    let db_conn = req.map.find::<PooledPostgresConnection>().unwrap();
    // use db_conn
}

That is all, enjoy!

Many thanks to Christoph Burgdorf, creator of Nickel.rs, and Steve Fackler, author of rust-postgres, for giving me a number of pointers to get things going.

Are we web yet? ... one step closer!

My First Rust Program - A Web Server Using Nickel.rs and rust-postgres

Rust is a new programming language, from Mozilla, which appeared on my radar recently.

I wanted to get my feet wet by writing a basic HTTP server that could read and write data from a database, and here is my first attempt: nickel-postgres

There are many things that I would like to improve about it - (see the numerous //TODO comments) - but I thought I would share my rookie attempt!

Many thanks to Steve Fackler, author of rust-postgres, for giving me a couple of pointers in the right direction.


Quick Select Algorithm, a Javascript Implementation

The function description comment says it all.

/*
 * Places the `k` smallest elements (by `propName`) in `arr` in the first `k` indices: `[0..k-1]`
 * Modifies the passed in array *in place*
 * Returns a slice of the wanted eleemnts for convenience
 * Efficient mainly because it never performs a full sort.
 *
 * The only guarantees are that:
 *
 * - The `k`th element is in its final sort index (if the array were to be sorted)
 * - All elements before index `k` are smaller than the `k`th element
 *
 * [Reference](http://en.wikipedia.org/wiki/Quickselect)
 */
function quickSelectInPlace(arr, k, propName) {
    if (!arr || arr.length <= k || typeof propName !== 'string') {
        throw 'Invalid arguments to quickSelectInPlace';
    }
    var len = arr.length;

    var from = 0;
    var to = len - 1;
    while (from < to) {
        var left = from;
        var right = to;
        var pivot = arr[Math.ceil((left + right) * 0.5)][propName];

        while (left < right) {
            if (arr[left][propName] >= pivot) {
                var tmp = arr[left];
                arr[left] = arr[right];
                arr[right] = tmp;
                --right;
            }
            else {
                ++left;
            }
        }

        if (arr[left][propName] > pivot) {
            --left;
        }

        if (k <= left) {
            to = left;
        }
        else {
            from = left + 1;
        }
    }
    return arr.slice(0, k);
}