Promises, Promises and more Promises (in jQuery)

I moved my blog to www.blinkingcaret.com. It has a new design an lots of great new blog posts.

Click here to read this post there.

A few months ago I answered a question on StackOverflow that got a lot of attention, especially after I’ve submitted it to Hacker News. The question was “Why are callbacks more tightly coupled than promises?”. I did not ask that question, but the current highest voted answer is mine, however as you can read from the comments on hacker news, there’s a bit of criticism, and some of it justified.

I’ve been meaning to write this post for a while. It describes

  • What is a promise
  • What problems do promises solve
  • What can you do with promises that you can’t with callbacks

It addresses some of the criticisms I got from the hacker news’ comments, and since it’s way too long for stackoverflow I’ve decided to put it here.

I won’t argue that using promises is superior to using callbacks, I’ll leave that to your judgement. So here we go, what is a promise?

Promises are objects which represent the pending result of an asynchronous operation
Martin Fowler (source)

They are also know as deferreds or futures.

The important thing here is that promises are objects, you can hold on to a reference to them, return them in functions and pass them as arguments to other functions, basically anything you can do with an object.

More importantly, you can combine them and create new promises from old ones (more on that shortly). But first let’s compare signaling the completion of an asynchronous method with a callback and with a promise.

Promise vs Callback

//The $.ajax returns a promise. You can either use it or supply a callback function for complete and/or error
var performAjaxRequest = function(onDoneCallback){
    return $.ajax(someUrl, {
        complete: onDoneCallback
    });
};

var performRequestUsingCallback = function(){
    performAjaxRequest(function(){ alert('Complete callback');});
};

var performRequestUsingPromise = function(){
    var performingRequest = performAjaxRequest();
    performingRequest.done(function(){
        alert('Promise done');
    });
};

I’ve added the performAjaxRequest function so it would match this example in jsFiddle using a fake ajax request.

Before I delve into the details of this example, let me first highlight a point that might be confusing. In jQuery there is the concept of Promise and Deferred, and they are not exactly the same thing (if you look at the jsfiddle example, you’ll see a deferred being created). They both represent an asynchronous operation, however a Deferred exposes methods to signal its completion (.resolve) or its failure (.reject). A promise is exactly the same thing without those methods. You can get hold of a promise by calling deferred.promise().

Things to note in this example:

  • You can call .done on a promise, the callback you supply will run after the asynchronous operation that the promise represents finishes (here’s the doc page for .done). This is implemented by calling .resolve or .resolveWith on the jQuery Deferred object.

When .resolve is called on a deferred it is possible to supply parameters, for example deferred.resolve(42). This will trigger a call on .done with the value 42, i.e., .done(function(x){ //x is 42}). For example, in $.ajax the deferred is resolved with (data, textStatus, jqXHR).

You can also call .fail, .always and .then on a promise:

  • .fail is called when the .reject method is called on the deferred object that represents the promise.
  • .always is called when .reject or .resolve are called in the deferred object
  • .then is special. It can do two things (and this is not clear in the jQuery documentation and depends on the version of jQuery), but the important thing to be aware is that .then always returns a new promise. The examples later in the post will make this clear.

This last example is not terribly interesting, however notice that when using promises the handling of the completion of the operation can be specified after the invocation of the asynchronous operation, for example:

showLoadingScreen();
var loadingData = loadData().done(refreshDataOnScreen, updateCounters)
                            .fail(logError, displayErrorMessage)
                            .always(hideLoadingScreen);

loadingData.done(doSomethingWithTheData);

NOTE: gettingData.done(doSomethingWithTheData); is shorthand for gettingData.done(function(data){doSomethingWithTheData(data);});.

The major difference between using a callback and a promise that this example highlights is that with the callback you only have one opportunity to provide the function that runs on completion (or error), whereas with a promise you can add several functions at different points in your code.

NOTE: when done, fail and always are supplied more than one function, those functions are executed in the order they are supplied (also, promise.done(fn1, fn2) is the same as promise.done(fn1).done(fn2)).

Another thing that you can do with promises that is enabled by them being objects is to create promises from promises. For example:

$.when(loadDataFromSourceA, loadDataFromSourceB).done(refresh);

$.when returns a new promise that is “resolved” when all its promises are resolved, and is “rejected” as soon as one of its promises is rejected (in the example when’s promises are loadDataFromSourceA and loadDatafromSourceB).

Although done, fail and always return promises, when is the first example where a new promise is returned, another example is .then.

.Then

.then is described in the documentation as a way to filter the result of a promise, for example:

var newPromiseCreatedWithThen = loadData().then(function(data) { return data.length});
newPromiseCreatedWithThen.done(function(dataLength) { 
    //dataLength is the length of data in the original promise 
};);

However, that’s not its most useful feature. You can return a new promise from from the callback you supply to.then. If you do that, it won’t act as a “filter”. It will act as a way of chaining asynchronous calls, i.e.:

loadDataFromA().done(refreshDataFromA)
               .then(function(dataFromA){ return loadDataFromB(dataFromA) })
               .done(refreshDataFromB);

The refreshDataFromA function will run as soon as loadDataFromA finishes. The call to loadDataFromB will start after loadDataFromA finishes, and refreshDataFromB will run at the end, after loadDataFromB finishes. This is useful in scenarios where you need the result of an asynchronous operation in order to perform the next asynchronous operation. When used this way the function name (.then) actually makes sense (here’s an example that compares .done and .then and shows that returning a promise from .then is given “special” treatment).

This behavior is actually described in the documentation for .then:

These filter functions can return a new value to be passed along to the promise’s .done() or .fail() callbacks, or they can return another observable object (Deferred, Promise, etc) which will pass its resolved / rejected status and values to the promise’s callbacks

However, as you can see, it’s very easy to miss (and in my opinion, not very clear).

A last note about .then. It might be tempting to say that it provides a solution to “callback hell”, for example:

$.ajax("loadDataUrl", {
    complete: function() {
        $.ajax("loadMoreData", {
            complete: function() {
            ....

Although it is true that if you use .then you won’t have nested callbacks, it is also true that there are ways of not rewriting this last example withough promises and nested callbacks. In fact, anything you can do with promises, you can do without.


Was this post helpful to you? Do you use Windows Phone? If so check out my app, Lectito, it’s a speed reader that you can launch from the browser

Lectito speed reader for windows phone

Get it here.


Finding out where in a codebase a jQuery event is being registered and unregistered with the special events api

I moved my blog to www.blinkingcaret.com. It has a new design an lots of great new blog posts.

Click here to read this post there.

jQuery allows you to define extra functionality around events, namely it is possible to define behavior that happens when the first event handler is registered (setup), each time a new event handler is added (add), removed (remove) and when the last event handler is removed (teardown).

This is how, for example, you take advantage of the special event’s api for the click event:

jQuery.event.special.click = {  
    setup: function(data, namespaces, handler) { },
    add: function(handlerObj) { },
    remove: function(handlerObj) { },
    teardown: function(namespaces) { },
    _default: function (event) { }
};

If you are wondering how the special events api is normally used, think of this scenario: you want all elements that have a click event handler registered in them to show a “hand” when the mouse hovers over them (this might be useful if you want to make a div clickable, which usually does not display any visual cues that let the user know that the div can be clicked). You also want this effect to go away as soon as the last event handler is unregistered.

You can achieve this without using the special events api by setting the cursor property when you register and unregister the click event:

$('#myElement').on("click", function(){
    $(this).css("cursor", "pointer");
    //...
};

The resetting of the cursor is more complicated, you’d have to keep track of the event handlers and remove it when you remove the last handler.

With special events it’s simple:

jQuery.event.special.click = {
    setup: function(){
        $(this).css("cursor", "pointer");
        return false; //this is important because click is a native event. It instructs 
                      //jQuery to use native DOM methods to register and unregister 
                      //the event (for custom events you don't need to return anything)  
    };
    teardown: function(){
        $(this).css("cursor", "");
        return false; //same as above
    };
}; 

Try it here

If you want to really understand the special events api, and really understand the example I suggest you read this

What does all this have to do with the title of this post? You can add debugger statements in any of the special event’s api methods, namely on add and remove so that you can find out (looking at the stack trace in chrome’s developer tools) where an event handler was registered and/or unregistered. This might be useful in large codebases that you are not familiar with, especially when someone decides to do something like $(someSelector).off() (which will deregister all events) and you are left wondering why you’re custom event isn’t firing.

The way to do it is to include the following snippet at the head of the page (after you include jQuery) you are analysing:

<head>
    <!-- after including jQuery -->
    
        $.event.special.YourCustomEvent = {
            add: function() {debugger;},
            remove: function(){debugger;}
        };
    

You can then using chrome with the developer tools’ console open navigate to the page and have the execution break every time a handler for YourCustomEvent is registered and unregistered.


Was this post helpful to you? Do you use Windows Phone? If so check out my app, Lectito, it’s a speed reader that you can launch from the browser

Lectito speed reader for windows phone

Get it here.


Quickly finding and debugging jQuery event handlers with findHandlersJS

I moved my blog to www.blinkingcaret.com. It has a new design an lots of great new blog posts.

Click here to read this post there.

tl;dr: Finding event handlers registered using jQuery can be tricky. findHandlersJS makes finding them easy, all you need is the event type and a jQuery selector for the elements where the events might originate. Examples can be found here. A working page with findHandlersJS loaded and ready to try can be found here.


Events and event handling are an important part of client-side development. Frequently we are tasked with changing their behavior and part of that process involves locating which methods handle which events. Unfortunately sometimes they can be difficult to locate, especially when we are dealing with a code base that we are not familiar with.

In this blog post I’ll describe an alternative that hopefully makes finding event handlers easier, in particular, event handlers registered using jQuery.

But first let’s look at how we can register an event handler using javascript.

Registering events and event bubbling with plain javascript

You can add event handlers in javascript using the addEventListnerMethod:

Html

<input type="button" id="myButton" value="Click me"/>
<span id="myLabel"></span>

Javascript

document.getElementById('myButton').addEventListener("click", function(event){ 
    //this is the event handler for the click event in myButton
    document.getElementById('myLabel').innerText=event.target.id + " was clicked"; 
});

Check it out here

One important thing to be aware about events is that they bubble. What this means is that every element in the hierarchy until the root element of the html will have a chance to handle the event.

Imagine this is describes your html page:

document 
    div
        p
          button

You can register an event handler on the button, in the paragraph that contains the button, the div that contains the paragraph or the document itself. They will all “see” the event. This is the reason why it is sometimes difficult to find where the particular event we are interested in is being handled. For example, the next example exhibits the same behavior as the previous one:

Html

<input type="button" id="myButton" value="Click me"/>
<span id="myLabel"></span>

Javascript

document.addEventListener("click", function(event){
    //this is the event handler for the click event that will be used if you click any element in the page
    document.getElementById('myLabel').innerText=event.target.id + " was clicked";
});

Try it here

Although this seems to produce the same end result, if you would go look for the event handler in the button itself, you would not find it.

Why would you use this technique then? This technique is popular when parts of the web page are injected via ajax calls. The document object is part of the page’s header object so you can always rely on document being available (which is handy if part of the webpage is going to be fetched sometime in the future), and register your event handlers there.

Registering direct and delegated events using jQuery

With jQuery, event handlers are registered using the .on keyword.

jQuery makes the distinction between event handlers that only handle events triggered in the element they were registered on (direct events handlers) and event handlers that handle events that were triggered in a subset of the children of the element they were registered in (delegate event handlers). The subset of the children is specified through a jQuery selector.

Here’s an example of a direct event handler that handles clicks in a button:

Html

<input type="button" id="myButton" value="Click me"/>
<span id="myLabel"></span>

Javascript

$(function(){
    $('#myButton').on("click", function(event){
        $('#myLabel').text(event.target.id + " was clicked");
    });
});

Try it here

Here’s an example of a delegate event handler that handles clicks in all buttons that exist now or that might be added in the future in the whole page:

Delegated events

Html

<input type="button" id="myButton" value="Click me"/>
<span id="myLabel"></span>

Javascript

$(function(){
    $(document).on("click", ":button", function(event){
        $('#myLabel').text(event.target.id + " was clicked");
    });
});

Try it here

The best place to find out more about delegate and direct events is the .on documentation page.

Finding event handlers using Chrome dev tools

Browser dev tools help you find event handlers, for example in Chrome you can right click anywhere in the page, for example on a button, and select “Inspect Element”. The event handlers will be shown in the Event Listeners tab (right side of the elements tab).

Event Listeners tab on chrome

A very handy feature of the tooling is that you can right click the “handler” and select show function definition:

Show Function Definition on Chrome

You can then add breakpoints and debug the event handlers. However if you use events registered with jQuery, you will see jQuery’s event handler. This is because jQuery adds additional functionality to the normal event handlers. This is one of the complicating factors that makes finding the actual event handlers we are interested in more difficult.

If you use findHandlersJS instead you’ll get directly to the actual event handlers.

findHandlersJS (works best in chrome)

The idea is that by specifying an event type (e.g. “click”), and which elements you are interested in, using a jQuery selector, you get all the event handlers that are triggered when you click one of the elements that are covered by the selector you specified.

Here’s an example

Imagine you are working on this web page:

simple form with save and cancel buttons

And you want to debug the event handler for the Save button. After you include findHandlersJS you could write in chrome’s console:

findEventHandlers("click", ":button:contains('Save')")

That would provide you with the following information

save button information from findHandlersJS

  • element
    The actual element where the event handler was registered in
  • events
    Array with information about the jquery event handlers for the event type that we are interested in (e.g. click, change, etc)

    • handler
      Actual event handler method that you can see by right clicking it and selecting Show function definition
    • selector
      The selector provided for delegated events. It will be empty for direct events.
    • targets
      List with the elements that this event handler targets. For example, for a delegated event handler that is registered in the document object and targets all buttons in a page, this property will list all buttons in the page. You can hover them and see them highlighted in chrome.

You can then hoover over the element property and chrome will highlight the element where the event handler was registered:

highlight of element where the save event handler was registered

You can also hover over function on the handler property and select Show function definition. That will show you the source code for that event handler. You can add breakpoints and debug the event handler method.

click show function definition source code for save

More examples:

findEventHandlers(“click”, “div#itemList :button”) would return information about all the jquery event handlers (direct or delegated) that handle a click in the buttons inside a div with id “itemList”.

findEventHandlers(“click”, “*”) returns all click event handlers, including those registered on the document object

findEventHandlers(“change”, document) returns the change event handlers registered on the document object

findEventHandlers(“addNewItem”, “div#items :button:nth(3)”) all event handlers that handle the custom event addNewItem for the the fourth button inside the div with id=”items”

Try these examples here.

You can get findHandlersJS in github here. You can just copy and paste the raw javascript code to chrome’s console window and just start using it, or if you want to use it in your project just make sure you add it after jQuery (I’ve tested it in versions >= 1.7.1. Might also work with older versions).

Any comments/suggestions are welcomed.


Was this post helful to you? Do you use Windows 8.1 or Windows Phone 8.1? If so check out my game, Memory Ace, it’s an educational game that teaches memorization techniques. With a little bit of training I’ve used it to memorize a full deck of cards without much effort. It’s great for keeping those neurons healthy!

Get the Windows 8.1 store version here.

Get the Windows Phone 8.1 version here.

Also for Windows Phone check out Lectito, it’s a speed reader that you can launch from the browser.

Lectito speed reader for windows phone

Get it here.


Interaction testing, fakes, mocks and stubs

I moved my blog to www.blinkingcaret.com. It has a new design an lots of great new blog posts.

Click here to read this post there.

Today I was procrastinating by reading unanswered questions at StackOveflow, when I noticed a question about what Mocks are. I though I could give a short answer, but I got carried away and gave a long one.

Only after posting it did I notice that the guy that asked the question is not a member anymore and the question is from 2009.

Probably it won’t be read by anyone there so maybe someone here will read it and find it useful. It’s about the difference between mocks and stubs, and why isolation frameworks are useful. It also addresses the differences between unit and integration testing, here it is:

To really understand Mocks you first have to grasp four concepts
What is interaction testing
What are isolation frameworks (like rhino mocks)
What is a fake
What is a stub
And finally what is a mock

Interaction testing is about checking if a particular method (the one you are testing) calls another method in another class (the external dependency) with the parameters it is supposed to use.
Imagine you have a method in some class that logs every time it is called with invalid parameters. For clarifying the difference between stubs and mocks I’ve added 2 external dependencies (IStringAnalyzer and ILooger):

 

class SomeClass
{
    IStringAnalyzer stringAnalizer;
    ILogger logger;

    public SomeClass(IStringAnalyzer stringAnalyzer, ILogger logger)
    {    
        this.logger = logger;
        this.stringAnalyzer = stringAnalyzer;
    }


    public void SomeMethod(string someParameter)
    {
        if (stringAnalyzer.IsValid(someParameter))
        {
            //do something with someParameter
        }else
        {
            logger.Log("Invalid string");
        }
    }
}

In this example you want to test if a method call to SomeClass’ SomeMethod with an invalid parameter calls the log method in ILogger with the string parameter “Invalid string”.
You *do not* want to use your “real” implementations of IStringAnalyzer and ILogger because these can have errors, and because this is *unit* testing you just want to test one thing at a time, if you test several things at a time what you are really doing is *integration* testing. The reason for only testing one thing at a time is that if your test fails you know immediately that it is failing because of that only one thing you tested.

You need to provide two alternative implementations, one for IStringAnalyzer and one for ILogger so that you can do this test properly. There will be a difference in these alternative implementations in terms of what they need to do. For IStringAnalyzer you just want that when it’s called it returns false, so that the method under test will go through the code path you want to test. You really don’t care about the parameter’s value (someParameter).

For ILogger’s log method you want to know that it was called, and that it was called with “Invalid string”, so that you can assert this in your test.

These two alternative implementations of IStringAnalyzer and ILogger are both called “fakes” (because they fake the external dependencies), but one is a Stub (IStringAnalyzer) and the other is a mock (ILogger). The stub is there only to get you to where you need to go in your test (in this case that IStringAnalyzer’s IsValid method returns false). The mock is there to allow you to check if the interaction with the external dependency was done properly (in this case ILogger). Some people refer to mocks (or to this type of mock) as a Test Spy (an infinitely better name in my opinion). And yes, there are other types of mocks (I’ve never used them though). A good source for this is Working with legacy code form Michael Feathers and Roy Osherove’s The art of unit testing.

You can create the stub and mock “by hand”, for example:

class StringAnalyzerStub : IStringAnalyzer 
{    
    public bool whatToReturn;

    public StubStringAnalyzerStub(bool whatToReturn)
    {
        this.whatToReturn = whatToReturn;
    }

    public bool IsValid(string parameter)
    {
        return whatToReturn;
    }
}


class LoggerMock : ILogger
{
    public string WhatWasPassedIn;

    public void Log(string message)
    {
        WhatWasPassedIn = message;
    }
}

 

And here’s the test:

[Test]
public void SomeMethod_InvalidParameter_CallsLogger
{
    IStringAnalyzer s = new StringAnalyzerStub(false); //will always return false when IsValid is called
    ILogger l = new LoggerMock();
    SomeClass someClass = new SomeClass(s, l);

    someClass.SomeMethod("What you put here doesnt really matter because the stub will always return false");

    Assert.AreEqual(l.WhatWasPassedIn, "Invalid string");
}

The thing about doing this by hand is that it is error prone and hard to maintain, hence the need for isolation frameworks like Rhino Mocks. They allow you to create these mocks and stubs dynamically, here’s how the same test would look like using Rhino Mocks (using the arrange, act, assert syntax):

[Test]
public void SomeMethod_InvalidParameter_CallsLogger
{
    Rhino.Mocks.MockRepository mockRepository = new Rhino.Mocks.MockRepository();
    IStringAnalyzer s = mockRepository.Stub<IStringRepository>();
    s.Stub(s => s.IsValid("something, doesnt matter").IgnoreParameters().Return(false);
    ILogger l = mockRepository.DynamicMock<ILogger>();
    SomeClass someClass = new SomeClass(s, l);
    mockRepository.ReplayAll();

    someClass.SomeMethod("What you put here doesnt really matter because the stub will always return false");

    l.AssertWasCalled(l => l.Log("Invalid string"));
}


TDD, BDD, [add every other method that promises software quality here] and the tea tasting lady

I moved my blog to www.blinkingcaret.com. It has a new design an lots of great new blog posts.

Click here to read this post there.

What can possibly TDD, BDD or adhering to SOLID have to do with a lady that is funny about her tea? Read on and I promise the answer will not be disappointing to you.

But first let me give you some context about what lead me to write this article. This last weekend I watched the third episode from http://www.cleancoders.com/. It’s about how you should go about creating your functions/methods, how big they should be, how you can actually have a “class hidden inside a method” (if you can watch it, it is very entertaining, it’s not free though).

Monday morning, in The Code Project’s “The Daily Insider” an article named “Readable code – and the long lost secret of how to achieve it” was referenced. That link points to a video that is a rebuttal of what is advocated in Uncle Bob’s video in the cleancoders. It tries to refute the idea that you should “extract ‘till you drop”, which means that you should try to make your methods smaller until you cannot make then any smaller. Her argument is that this actually makes code harder to read.

Usually what people do in a situation like this is to bring their own personal experience and affirm, certain of themselves, that their view is the right one (just read the comments on the readable code video). The discussion that ensues usually leads nowhere.

Now comes the story of the lady that was peculiar about her tea. She liked her tea with milk, but you had to put the milk first and then the tea, or else she said, the tea would be ruined. Your reaction (as mine was) is that it is impossible to tell the difference. But how can you prove it?

Well, if you give the lady one cup of tea with milk added first, she has 50% change of getting it right. If you give her two cups of tea (with milk or tea added first randomly), she now only has 25% chance of getting it right. If you were to give her 5 randomly filled cups of tea with milk, her chance of getting them all right is around 3% (we usually say that a result is significant if the chances of getting it randomly are <5%).

Well, this story is real, and she was really able to tell the difference (I don’t actually remember which one she preferred, milk with tea or tea with milk, but you can look the story up in this amazing book from Andy Field: “How to design and report experiments”).

Apparently she was able to correctly classify 8 cups of tea (the chances of she getting that right by chance are <1%) (check http://en.wikipedia.org/wiki/The_Lady_Tasting_Tea and http://en.wikipedia.org/wiki/Lady_tasting_tea).

That’s how you settle a dispute, try arguing with that. You can’t. Why don’t we apply this same reasoning to the claims that BDD, TDD, etc, lead to better code. I’m not saying that they don’t, I actually believe they do, but if you test them scientifically you can actually measure how much better they are, you can compare them, you can extract other useful information, for example, how much more time one takes in relation to the other and if the increase in immediate quality is worthy of that cost.

It’s a very hard thing to get right (http://blog.jove.com/2012/05/03/studies-show-only-10-of-published-science-articles-are-reproducible-what-is-happening/) but we should really think about doing it more often in our domain.


Using ASP.NET MVC’s Html.DropDownListFor helper

I moved my blog to www.blinkingcaret.com. It has a new design an lots of great new blog posts.

Click here to read this post there.

Html.DropDownList is used when you need to create a view that has a dropdown that allows you to select one of several possible values for one of your model’s properties.

For example you have a Model that describes a Employee. One Employee has one Manager and in the Employee’s Edit view you want to display a drop down with all the possible values for Manager.

So the goal is to have something that looks like this:

image

Here’re the models that you can use to try to build this canonical example yourself:

First, the employee model:

public class Employee
{
    public int Id { get; set; }
    public string Name { get; set; }
    public int ManagerId { get; set; }
}

In the view I added the managers as a list of person, here’s the Person class:

public class Person
{
    public int Id { get; set; }
    public string Name { get; set; }
}

Now the controller (just the edit actions):

public ActionResult Edit(int id)
{
    //Fetch employee            
    Employee employee = new Employee();
    employee.Id = id;
    employee.ManagerId = 4;
 
    //Fetch managers
    List<Person> managers = new List<Person>()
    {
        new Person() { Id = 1, Name = "John"},
        new Person() { Id = 2, Name = "Richard"},
        new Person() { Id = 3, Name = "Peter"},
        new Person() { Id = 4, Name = "Paul"}
    };            
 
    ViewBag.ManagerId = new SelectList(managers, "Id", "Name", employee.ManagerId);            
    return View(employee);
}
 
[HttpPost]
public ActionResult Edit(Employee employee)
{
    //you should find your model binded employee here
}

For the sake of simplicity all values are hardcoded.

Important things to note about the controller’s edit action:

  • The adding of the ManagerId to the ViewBag as a SelectList containing all the managers, the value field (Id), the description field (“Name”) and the selected value (employee.ManagerId)
    • A SelectList represents a list where one of the items can be selected. It allows you to specify which is the value that should be returned, the desciption, optional text and which item is selected by default (see http://msdn.microsoft.com/en-us/library/system.web.mvc.selectlist.selectlist). It is a convenient way to set the values when using the html helper DropDownList
    • The fact that it was added to the ViewBag as ManagerId is also important. ManagerId is the name of the property that we want to set in the Model (Employee)

If you use scaffolding to add the Edit view by right clicking on View(employee) and selecting Add View:

image

You’ll be disappointed to find out that the view will display a textbox where you can type the Id of the Manager (at least if you are using Visual Studio 2012 RC and an MVC4 project template, although I didn’t test I think this used to work in MVC3). Not ideal. But it is easy to fix, but first let me show you what you’ll get when you use scaffolding:

@Html.LabelFor(model => model.ManagerId)
@Html.EditorFor(model => model.ManagerId) @Html.ValidationMessageFor(model => model.ManagerId)

Not what we want, but it is very easy to change, just change the EditorFor( mode=> model.ManagerId) to @Html.DropDownList(“ManagerId”, string.Empty) and you are done.

There are a few conventions here that make this to work:

  • The Html.DropDownList will look in the ViewData (ViewBag) for an entry with key “ManagerId” that contains a SelectList (an IEnumerable<SelectListItem> would work as well)
  • It will generate an html select element with a name attribute value of “ManagerId”. This is important because MVC’s model binder will look inside the post data for elements with the same name as the properties in the model, in this case Employee. Because Employee has a ManagerId property and the post data contains an element with that name the model binder will fill it as we intend.
  • The string.Empty is a value that is added to the beginning of the list. Think of it as representing that the employee does not have a manager.

If you think this is too much convention and it makes it difficult to understand what is going on you may think it is better to use one of the overloads of Html.DropDownList. For example, you might be tempted to do this:

@Html.DropDownList(“ManagerId”,  (SelectList)ViewBag.ManagerId, string.Empty)

Remember that ManagerId in the ViewBag contains a SelectList the was initialized with all the managers, one optional value and a selected value. The selected value will not work (won’t be selected) if your DropDownList’s name is the same as the model property (see http://stackoverflow.com/questions/624828/asp-net-mvc-html-dropdownlist-selectedvalue). I don’t really know why this happens (if you find out please let me know).

However if you set the SelectList in the ViewBag with a different name than your model’s property the select that is rendered will behave as expected and the model binding will still work:

public ActionResult Edit(int id)
{
    //Fetch employee            
    Employee employee = new Employee();
    employee.Id = id;
    employee.ManagerId = 4;
 
    //Fetch managers
    List<Person> managers = new List<Person>()
    {
        new Person() { Id = 1, Name = "John"},
        new Person() { Id = 2, Name = "Richard"},
        new Person() { Id = 3, Name = "Peter"},
        new Person() { Id = 4, Name = "Paul"}
    };            
 
    ViewBag.Managers = new SelectList(managers, "Id", "Name", employee.ManagerId);            
    return View(employee);
}

@Html.LabelFor(model => model.ManagerId)
@Html.DropDownList("ManagerId", (SelectList)ViewBag.Managers, string.Empty) @Html.ValidationMessageFor(model => model.ManagerId)

Or alternatively you can use DropDownListFor:

@Html.LabelFor(model => model.ManagerId)
@Html.DropDownListFor(model => model.ManagerId, (SelectList)ViewBag.Managers) @Html.ValidationMessageFor(model => model.ManagerId)

Was this post helful to you? Do you use Windows 8.1 or Windows Phone 8.1? If so check out my game, Memory Ace, it’s an educational game that teaches memorization techniques. With a little bit of training I’ve used it to memorize a full deck of cards without much effort. It’s great for keeping those neurons healthy!

Get the Windows 8.1 store version here.

Get the Windows Phone 8.1 version here.


Where’s my ID?

I moved my blog to www.blinkingcaret.com. It has a new design an lots of great new blog posts.

Click here to read this post there.

Retrieving the value of an identity column from a record in a database table after inserting it may sound ridiculously simple (and it is), however if you google for it you will find that people often have problems with it when using ADO.NET, specifically if they are not using SQL Server.

First of all, let me say that adding a row to a datatable, updating it using a table adapter and then refreshing the table is not a solution to this problem. This is a very bad idea:

BooksDataset booksDataSet = new BooksDataset();
BooksDatasetTableAdapters.BooksTableAdapter booksTableAdapter = new BooksDatasetTableAdapters.BooksTableAdapter();
booksTableAdapter.Fill(booksDataSet.Books);
var newBookRow = booksDataSet.Books.NewBooksRow();
newBookRow.Author = "Some Author Name";    
newBookRow.Name = "Some Book Name";
booksDataSet.Books.AddBooksRow(newBookRow);
booksTableAdapter.Update(booksDataSet.Books);
booksTableAdapter.Fill(booksDataSet.Books);
Console.WriteLine(booksDataSet.Books.Last().ID);

This might seem to work, but given enough time it will bring you problems because between the Update, the Fill and the retrieving of the ID of the last record many things might happen in a concurrent environment, namely another row might get inserted or the row you’ve inserted might have been deleted.

If you are using SQL Server everything works great you’ll probably never have to worry about this. However, if you are not, and my personal experience is with MySQL, specifically using MySQL with the ODBC connector, the wizards of Visual Studio do not help you as much as if you were using SQL Server. If you are not interested in resorting to stored procedures to solve this problem, read on.

But before we go into the solution, let’s just look at how what gave this post it’s title. The auto-generated ID columns whose values we so desperately want to get.

First let’s look at the ways you can get the generated ID for an inserted row in SQL Server. The need to understand this next part will become clear at the end. Trust me.

SCOPE_IDENTITY()

From the msdn documentation: “Returns the last identity value inserted into an identity column in the same scope. A scope is a module: a stored procedure, trigger, function, or batch. Therefore, two statements are in the same scope if they are in the same stored procedure, function, or batch.”

@@IDENTITY

The difference between @@IDENTITY and SCOPE_IDENTITY is that @@IDENTITY will “return the last identity values that are generated in any table in the current session”

“For example, there are two tables, T1 and T2, and an INSERT trigger is defined on T1. When a row is inserted to T1, the trigger fires and inserts a row in T2. This scenario illustrates two scopes: the insert on T1, and the insert on T2 by the trigger.

Assuming that both T1 and T2 have identity columns, @@IDENTITY and SCOPE_IDENTITY will return different values at the end of an INSERT statement on T1. @@IDENTITY will return the last identity column value inserted across any scope in the current session. This is the value inserted in T2. SCOPE_IDENTITY() will return the IDENTITY value inserted in T1. This was the last insert that occurred in the same scope. The SCOPE_IDENTITY() function will return the null value if the function is invoked before any INSERT statements into an identity column occur in the scope.”

This is all from the msdn documentation.

Lastly, for SQL Server, there’s the IDENT_CURRENT(‘table_name’) that gives you the “last identity value generated for a specified table or view. The last identity value generated can be for any session and any scope.”

For MySQL you can use LAST_INSERT_ID(), and to ensure you that this is what we really want have a look at this from MySQL’s documentation:

“The ID that was generated is maintained in the server on a per-connection basis. This means that the value returned by the function to a given client is the first AUTO_INCREMENT value generated for most recent statement affecting an AUTO_INCREMENT column by that client. This value cannot be affected by other clients, even if they generate AUTO_INCREMENT values of their own. This behavior ensures that each client can retrieve its own ID without concern for the activity of other clients, and without the need for locks or transactions.”

Now that we have got that out of the way, let’s talk about the reason why you can’t immediately retrieve the ID when you add a record to a database through a table adapter update. Specifically, why this will get you in trouble:

BooksDataset booksDataSet = new BooksDataset();
BooksDatasetTableAdapters.BooksTableAdapter booksTableAdapter = new BooksDatasetTableAdapters.BooksTableAdapter();
booksTableAdapter.Fill(booksDataSet.Books);
var newBookRow = booksDataSet.Books.NewBooksRow();
newBookRow.Author = "Some Author Name";
newBookRow.Name = "Some Book Name";
booksDataSet.Books.AddBooksRow(newBookRow);
booksTableAdapter.Update(booksDataSet.Books);
Console.WriteLine(newBookRow.ID);

Assuming that you are using a strongly typed dataset, in this case that’s BooksDataSet, and you used the wizzard to generate that strongly-typed dataset and the corresponding table adapters. If you are using SQL server as your database that will print the new ID value into the console. If you are using another database, chances are that won’t be the case.

For me it was MySQL, and what I got was –1. There are a couple of reasons why this happened, let’s go through them:

First, the Visual Studio 2010 wizard does not generate an Insert command for the table adapter that refreshes the data:

imageThat is what you will get if you poke in your dataset’s configuration (just go to the designer, right-click the dataset, configure). The good news is that you can edit the commands yourself, and it is very very easy, trust me. I’ll just show you how to do the Insert one:

image

image

See the highlighted part, that’s what we are going to change. (By the way, that’s what you’d get if you’re using MySQL, the “?”s give it away, there are no named parameters in MySQL). You actually have to type a version of this for your particular table:

INSERT INTO books
                         (Name, Author)
VALUES        (?, ?);
SELECT ID, Name, Author FROM books
WHERE ID = LAST_INSERT_ID()

And when you press OK you’ll get a warning stating “Unable to parse query text.”. Just click ignore.

But wait! Don’t go try this just yet. You need to be able to perform multiple statements. This is very important, and this is why you see so many people complaining that they can’t get this to work. Search for the FLAG_MULTI_STATEMENTS here. This is for the ODBC connector for MySQL. Just so you can understand how that can be hard to find here’s how you turn that on for the MySQL’s ODBC connector:

image

 

There you go.

If you did not TL;DRed by now, here’s why it’s important to be aware of the intricacies of IDENTITY, SCOPE_IDENTITY  (SQL Server) and LAST_INSERT_ID (for MySql). For this particular scenario it should be clear that you should use SCOPE_IDENTITY (and this is assuming that you need to fiddle with the auto generated commands for some reason) because if you use @@IDENTITY you can get an autogenerated ID for some other table where a record has been inserted, and this might very well happen given sufficient concurrent writes happening at your database.

LAST_INSERT_ID is the only alternative I know for MySql.

Relevant Links:

Connector ODBC: http://dev.mysql.com/downloads/connector/odbc/

Adding Commands “by hand” to a table adapter: http://www.vbmysql.com/articles/vbnet-mysql/myodbc-connector

SQL Server Identity Column values (meaning of @@identity, Scope_identity()): http://msdn.microsoft.com/en-us/library/ks9f57t0.aspx

Managing an @@IDENTITY Crisis: http://msdn.microsoft.com/en-us/library/ms971502.aspx

“How Microsoft Does It ”: http://www.davidhayden.com/blog/dave/archive/2006/02/16/2803.aspx

How to Get the Unique ID for the Last Inserted Row: http://dev.mysql.com/doc/refman/5.0/en/getting-unique-id.html


Follow

Get every new post delivered to your Inbox.

Join 270 other followers