How to set the initial selected value of a select element using Angular.JS ng-options & track by

I have been doing Angular.JS in production projects for months, that it did surprise me recently how I haven’t used drop-downs in it. Well, I mean how I haven’t used them enough to get into several problems I had in my current project, and other friends at the same office had in their project as well.

To save you the pain I went through, I’ll list some problems and solutions here, and then give you a video that shows going through all of them ans the thought process that led to the solutions.

Initial selection

Assuming someObject in the model has the same properties and values as someObject in the objectList, it will still not be selected.

It’ll only be selected if someObject was actually one of the objects in objectList, like objectList[0] or whatever. Otherwise, Angular.JS will insert an empty option tag with no value or text and select that.

Root Cause

Angular.JS uses native JavaScript comparison for comparing the objects. In JavaScript, unrelated to Angular.JS or anything, comparing objects (object literals) is “by reference”, so it doesn’t factor the similarity of the objects. Only checks if the two references compared point to the same object in memory or not.


An un-documented (AFAIK) feature in ng-options is that you can use some bits from the ng-repeat directive with it, like track by. This allows us to choose some property as the comparison key.

If the key property is a simple type, like Number or string, JavaScript will consider it equal to any other object that has the same value, so we don’t have to use the same objects.

Invalid Value Sent On Server-Side Submit

When Angular.JS writes the <option> tags from an ng-options directive pointing to an array, the value of the option is always the index of the element it maps to in the array. This is not important if you process the selection on client side because you only deal with the result of ng-model anyway, you can use this later to create an AJAX request or whatever.

However, if you intend to submit the form using a normal server submission, and only use Angular.JS for say validation or managing complex form interaction (client-side tables containing sub-items with add/remove/sort for example), this may be a road blocker to using Angular.

Root Cause

By default Angular.JS uses the index of the array to track which object maps to which <option> element.


Similar to the previous problem, use the track by syntax. Angular.JS will use the track by property value as the <option>‘s value. Most of the time your tracked property is the key property you want to send to the server anyway, so, this should be good enough.

Simple Properties Scenario When Combined With Server-Side Submit

Let’s say you want something as simple as this:

This syntax will work very well, if you only use this value from JavaScript, you are all set. But if you plan to send it directly to the server (a normal non-AJAX form submit), you’ll want to consider using the track by syntax, like track by

However, if you do this, you’ll notice that the select is no longer usable. No initial selection, and changing selection although updates the model, it does not show the new selected value.

Root Cause

The track by syntax expects an object, with the property you use to track. It does not honor the key part used in the key as text syntax (which in our example is as g.text), so, it wants the ng-model to point to an object with the tracked property, it cannot be the key itself directly.


I didn’t call this a solution, because it’s pretty much a hack.

We created a new property (which I liked to prefix with _ to show it doesn’t normally belong to the model object), initialized it to a new object that contains only our key property id set to the original simple value genderId, and then used that as the model (as in ng-model).

We created and assigned the property in ng-init, then synchronized the changes to the simple property via ng-change. This allows the code everywhere else in the application (like the controller, or other parts of the markup) to only interact with the property we want (genderId in this example), without knowing about our hack. This makes things a bit cleaner, although it still remains a hack rather than a solution.

You can view an example of using this hack here.

Adding extra selection items to the dropdown

One thing you notice if you are affected by the “initial selection” problem, is that the empty <option> tag that Angular.JS adds when it can’t match the ng-model to the array from ng-options disappears when the use changes their selection. We have gone through how to avoid showing the empty option by mistake already.

But if you do want to have that option, it’s easy, just, um, add it!


If you are using Angular 1.4+, check the much smaller 2nd part of this article, about how to use track by correctly.
Using track by correctly with Angular 1.4 select ng-options – Why can’t I select this option?

The Video

If you want to dig these problems really deep and see what they look like in action, and what was the thought process for solving them like and in some cases other possible solutions, I have put all this in a (rather long) video here:

Videos from ALT.NET Sydney Usergroup, 30 July 2013

Continuing my experiments of recording the few events I attend in Sydney using a simple Galaxy S4 phone, this time I’m posting videos from Sydney ALT.NET usergroup gathering in July.

Of course if you are interested in all the videos I put online, including a few tutorials I have created myself instead of just recording, check out my channel on YouTube.

Now to the videos…

Applications of the Reactive Extensions framework

By Niall Connaughton, @nconnaughton on twitter

Moving to HTTPS

By James Crisp, @jtcrisp on twitter

Final Note

Please let me know if you find these videos useful. I may not be able to do much about the quality in the short term, so, it’s worth knowing if the videos as-is are helping, or I need to pause until I get better tooling than just my phone camera and a simple webcam.

So, check out all the videos on YouTube, leave comments ion them, and let me know the topics that interest you, which may in the future turn into tutorials I create myself, or suggestions to ask usergroup leaders to look for presenters to talk about.

My 2nd On YouTube: Chrome Website App Shortcuts

The first video I published on YouTube (on Angular.JS directives and data-binding) seemed to be going very well. This made me easily fall into the issue I avoided before, which is worrying too much about what might follow. To get that worry off me, I chose a simple topic targeting different audience, recorded and edited it in one night, and just published.

The Video

This video targets Google Chrome user. It shows a productivity tip that I heavily rely on on my daily PC usage. I have many application-like websites pinned to my taskbar, ranging from TweetDeck to Outlook 365 Web Access. In this video, I simply show how to create these icons. the video is only about 5 minutes in length.

Load any website like an application using Google Chrome

Going Forwards: Suggestions Please!

There are several things I need to work on to make these experiments more useful (and fun) for everybody. Mainly I need to get used to talking to the mic so that I don’t get that dry throat that I don’t usually have even when facing many people in my offline live events, but also, I need to find topics that YOU guys and ladies are interested in. I’ll try to stick with short videos for now, but please, if you have any idea for the next video, just let me know, and I promise to consider it seriously.

Thank you very much.

My 1st YouTube Video: Angular.JS Directives Demo

So, my wife has been encouraging me to get this starting over the past 4 years or so. I was more busy with offline groups at first, followed by traveling to work in different countries, and then later all sorts of new stuff I wanted to learn around .NET, software craft in general, and web development and trends. At last, I started, and uploaded my first YouTube video.

The Video

To make sure I actually get to the point where I have something to upload, I used the Minimum Viable Product approach. I looked for a simple topic that I still think you guys might be interested in, I spent some time on editing the video but still didn’t wait till I’m 100% happy about the quality (particularly of my own voice) before publishing. The idea is that if I continue to do this I might be able to get more out soon and practice will naturally increase the quality. Was that the right way to do it? Only your feedback can tell!

Simple Angular.JS Demo: Using HTML Directives Even Without JavaScript Controllers

Now It’s Up To You!

As you may expect, I’m really looking forwards to all sorts of feedback on this video. Let me know whether you liked it, and what would you’d like to see in future videos. If there is any question, problem, or idea that you’d be interested in seeing me talk about it, please let me know.

Thanks a lot.