Category Archives: JavaScript

Backbone and ASP.NET MVC: Use Nullable types as Id

As a side note to my blog post about renaming the idAttribute in Backbone when using it with ASP.NET (MVC), this post continues with the Id attribute.

The Id attribute in Backbone is very important. Backbone uses it to determine if an object is new, or already existed. Collections use it to determine if it already contains any given object.

So I ran into a problem in a situation where my model required a lot of “supporting data” before it was saved. To add this data, I decided to create the models on the server and add it to a collection (since there were a whole list of them).

No matter how many models I added to the list, only the first one was rendered. Why? Because my model on the server was using a non-nullable Integer as its Id property like this:

public class Account
{
	public int Id { get; set; }
}

So of course, all the models returned from the server had an Id of zero! And of course, Backbone thought that they were all the same instance since they shared the same Id.

Small change, huge impact

Talk about a single character making a huge impact!

By adding the silly question mark to the Id property, everything was working. That’s because a Nullable integer is not added to the JSON returned by the server, and Backbone then knows that this model does not exist!

Backbone and ASP.NET MVC: Rename the ID attribute

In Backbone, a model’s ID attribute is vital in the way Backbone handles models and collections. In a collection, you can call get with an ID and you’ll get back the model.

The thing is, naming conventions across languages does not always agree. In .Net properties are named in PascalCase. In JavaScript camelCase is the standard, so naturally this leads to a conflict when your model in Backbone names the ID attribute id, and the corresponding domain model on the server side is named Id.

I was using an ASP.NET MVC controller to return a collection of Accounts, but when it hit the client, got changed and later saved, the ID was lost and the model was created as a new instance in the database.

The problem was that when Backbone fetched the collection, and automatically turned the objects in the array into instances of Account — Backbone was expecting to find every model’s ID in the id property, which did not exist. And on the server, it uses Id to know if this model is new or already exists.

Change the idAttribute

It turns out that Backbone is designed for this.

Whenever you define your models, you need to set the value of the idAttribute property like this:

var Account = Backbone.Model.extend({
	idAttribute: "Id"
});

But that’s a bit annoying since you’ll have to remember this on each and every model. And you need to define your own model every time, you can’t just create a new instance of the stock Backbone.Model class.

But with JavaScript being the awesome language that it is, you can change the prototype like this:

Backbone.Model.prototype.idAttribute = "Id";

And now you can totally forget about this, and let Backbone handle IDs properly!

Backbone.js Compatible Routes for, non-Web API, ASP.NET MVC projects

Backbone.js has become my JavaScript MV* framework of choice (you do use a JavaScript MV* framework, to structure JavaScript, right?). I find myself using ASP.NET MVC for less and less that has something to do with views, and other stuff that belongs on the client.

The server, being ASP.NET MVC, is the new backend now a days. I’m sure that’s how Microsoft sees it as well, with the release of Web API.

cc by-nc-nd Bruno Monginoux www.photo-paysage.com & www.landscape-photo.net

When using models in Backbone, and specifying the urlRoot setting, Backbone will automatically construct URLs to do CRUD operations against your server. It uses RESTful URLs, and regular ASP.NET MVC controllers are not compatible with those out of the box.

Consider this Backbone model and collection:

var Account = Backbone.Model.extend({
	urlRoot: "/accounts"
});

var AccountCollection = Backbone.Collection.extend({
	model: Account,

	url: "/accounts"
});

When you save a new Account, Backbone will make a POST request to your server expecting to hit your AccountsController. But with regular MVC controllers (non-Web API, that is) the routing won’t succeed, since the default {controller}/Index action only works with the default, parameter less GET request.

You might think that this controller will work:

public class AccountsController : Controller
{
	[HttpGet]
	public JsonResult Index()
	{
		List accounts = new List();
		accounts.Add(new Account { Id = 1, Name = "Account 1" });
		accounts.Add(new Account { Id = 2, Name = "Account 2" });
		accounts.Add(new Account { Id = 3, Name = "Account 3" });

		return Json(accounts, JsonRequestBehavior.AllowGet);
	}

	[HttpGet]
	public JsonResult Index(int id)
	{
		return Json(new Account { Id = id, Name = "Account " + id }, JsonRequestBehavior.AllowGet);
	}

	[HttpPost]
	public JsonResult Index(Account model)
	{
		return Json(model);
	}

	[HttpPut]
	public JsonResult Index(int id, Account model)
	{
		return Json(model);
	}

	[HttpDelete]
	public ActionResult Index(int id)
	{
		return View();
	}
}

But as mentioned before, the default Index routes doesn’t work that way. This won’t even build, since the method signature of Get and Delete are the same.

Route constraints to the rescure

Ideally we want our controller to look like the following:

public class AccountsController : Controller
{
	[HttpGet]
	public JsonResult GetAll()
	{
		List accounts = new List();
		accounts.Add(new Account { Id = 1, Name = "Account 1" });
		accounts.Add(new Account { Id = 2, Name = "Account 2" });
		accounts.Add(new Account { Id = 3, Name = "Account 3" });

		return Json(accounts, JsonRequestBehavior.AllowGet);
	}

	[HttpGet]
	public JsonResult Get(int id)
	{
		return Json(new Account { Id = id, Name = "Account " + id }, JsonRequestBehavior.AllowGet);
	}

	[HttpPost]
	public JsonResult Create(Account model)
	{
		return Json(model);
	}

	[HttpPut]
	public JsonResult Update(int id, Account model)
	{
		return Json(model);
	}

	[HttpDelete]
	public ActionResult Delete(int id)
	{
		return View();
	}
}

So for this to work, we need to point the individual HTTP verbs to their own action. This can be done by adding an HTTP method route constraints, when mapping routes in your RouteConfig (or Global.asax):

routes.MapRoute("Model_GetAll", "{controller}", new { action = "GetAll" }, new { httpMethod = new HttpMethodConstraint("GET") });
routes.MapRoute("Model_GetOne", "{controller}/{id}", new { action = "Get" }, new { httpMethod = new HttpMethodConstraint("GET"), id = @"^\d+$" });
routes.MapRoute("Model_Post", "{controller}", new { action = "Create" }, new { httpMethod = new HttpMethodConstraint("POST") });
routes.MapRoute("Model_Put", "{controller}/{id}", new { action = "Update" }, new { httpMethod = new HttpMethodConstraint("PUT") });
routes.MapRoute("Model_Delete", "{controller}/{id}", new { action = "Delete" }, new { httpMethod = new HttpMethodConstraint("DELETE") });

Now you can code away in Backbone, and always hit the correct MVC controller actions. If you want to avoid this, upgrade your MVC app to MVC 4 and use Web API controllers. They support this out of the box.

10 Ways to (re) Structure JavaScript

Structuring JavaScript can be a job in itself if you don’t look out. I was attending the virtual jQuery Summit 2011, and one of the talks were called ‘Structuring Your DOM-based Application‘ by Garann Means. Her talk really took me back to the days of fighting un-structured JavaScript.

I was working on a code base that had been maintained by a handful of different developers, each with different skills, ideas and disciplin. Web development, and especially JavaScript requires a lot of disciplin in order to keep the code clean and structured, and that just wasn’t the case at that time.

While I was watching Garann’s talk, I constantly thought of all the problems we had and what we eventually did to solve our issues and take control of our JavaScript.

This is is my 10 ideas on ways to (re) structure JavaScript, get it under control, get rid of legacy code and improve the quality of a code base.

1. Move all JavaScript code into js files

While this should be obvious for all of us, it’s just something I constantly see people don’t do. Instead of having these nice js files, JavaScript is thrown into view files.

First of all, this means that the same code is delivered to the client everytime a page is requested. Depending on the amount of JavaScript tucked into the view, this can easily add up to hundreds of kilobytes which slows down your sites load time. With JS files, you can easily cache those files on the client, save bandwidth and increase the speed of your site.

Secondly, it makes the JavaScript much more difficult to maintain. You basically can’t find what you’re looking for, it’s hard to have shared and general purpose functions that you can use from several views and you declare everything in the global scope.

2. Use closures, to avoid working in the global scope

JavaScript’s biggest problem is its dependence on global variables, particularly implied global variables. If a variable is not explicitly declared (usually with the var statement), then JavaScript assumes that the variable was global. This can mask misspelled names and other problems.

Douglas Crockford, http://www.jslint.com/lint.html – (Global Variables paragraph)

To solve this problem, we need to wrap all of our code in closures.

A closure changes the context your code is executed within, to be inside the closure and not in the global scope. This means that all your functions and variables inside your closure is not available for others, outside the closure unless you explicitly expose them.

A closure is often referred to as an Immediately Invoked Function Expression (IFFE), and it is pretty much a function that acts as a wrapper around your code:

(function () {
  // your code here
})();

Read more about closures and IIFE’s here.

3. Improve jQuery selectors

jQuery selectors are very powerful. It’s dead easy to write selectors that gets a bunch of elements in the DOM, and they can easily get pretty advanced.

This can have an impact on the performance of your code. Running in the browser, the efficiency of your code has a direct impact on the user’s experience.

Since getElementsByClassName is not implemented by all browsers, the ones that don’t have it will suffer when you query the DOM by class class name.

That means you can speed up your jQuery selectors by specifying the tag name before the class name:

BAD: $(".price-label")

GOOD: $("span.price-label")

You can also improve performance by limiting the context in which you select. You do that by specifying a second parameter to the selector which could be a container element that you’re working inside:

var productDetailsDiv = $("div.product-details");
var priceLabel = $("span.price-label", productDetailsDiv);

4. Cache elements, instead of selecting from the DOM

Using jQuery to select elements from the DOM is expensive. Some selectors are more expensive than others, but if you’re going to use the same element multiple times in a functions, you’re better off storing it in a local variable instead of selecting it every time.

When you select an element like this: $(".price-label") it’s like having a huge swimming pool (the DOM), and telling your little brother (jQuery) to jump in and find all USD coins in there. And if you do the same on the next line of code, he has to jump in again, swim around the pool looking for USD coins.

And if the pool is junked up with loads of coins in other currencies, he has to look at each end everyone of them to determine whether or not it is a USD coin.

Some browser has a native function called getElementsByClassName, as opposed to getElementsByTagName. That does speed up the above example a little, but it is still much more effective to cache the element in a local variable.

It’s just a matter of saving an element to a local variable, and the use that in the rest of you code:

var productDetailsDiv = $("div.product-details");
var priceLabel = $("span.price-label", productDetailsDiv);

5. Get rid of HTML in JavaScript

Just like JavaScript should not be added to your HTML pages, HTML should not be generated inside JavaScript by concatenating strings.

Client side template libraries are getting more and more popular, so utilize the <script type=”text/template”></script> and embed your client side view templates there.

Or even better. Pre-compile your client side views into JavaScript using something like HoganJS, place the code in a separate file and embed that. Not only will the footprint be smaller, but you also get caching and you speed things up since they’re already compiled!

6. Upgrade jQuery

This should be a no-brainer. But code-bases get stuck on old versions for a variety of reasons. Maybe you rely on a plugin that doesn’t work with the latest version, or you use lots of deprecated stuff that would take ages to rewrite.

Plugins that are stuck on older version, and are not compatible with future versions must die! You should not hold yourself hostage due to a plugin – get rid of it, fix the error, rewrite the plugin yourself and host it on Github. Never get stuck!

Same for deprecated code. It’s a huge warning signal and you need to react!

In general, stay up to date on the project. New concepts, bug fixes and performance improvements are added all the times. Subscribe to their blog, read the release notes everytime they release a new version to get familiar with the new stuff.

7. Teach your colleagues

It is widely misunderstood, but a lot of developers tend to think of JavaScript as a language you don’t have to learn, in order to write and maintain it. I don’t know of any other language where this is the case, but loads of developers just think of JavaScript as “not real code” that “just lives in the browser”, and more or less “doesn’t matter”.

This is one of the many reasons why JavaScript gets out of control. Too many incompetent developers are writing it, and it’s a tough job to get it under control if you’re the only true JavaScript developer where you work.

First of all, tell your colleagues to watch JavaScript – The Good Parts by Douglas Crockford. This touches on what’s great and what’s bad in JavaScript, and any developer that don’t really know the language will realize that they’re doing a lot of stuff wrong.

If you have to write JavaScript – man up and learn the language.

8. Combine, compress and cache your JavaScript.

In order to increase the performance of any website, minimizing the amount of files the browser needs to download, and minimizing the size of each file is vital.

First of all, install YSlow in your browser and start examining what you have to improve.

If you haven’t optimized for fewer HTTP request, you’ll notice that’s the top thing YSlow tells you to do. Find inspiration and guidance on how to minify and optimize JavaScript and CSS files. It’s easy.

Next up is caching. First thing on this list, suggests that you should move JavaScript into js files. And this is why: Having js files, that is embedded on a page makes it really easy to cache on the client. Most webservers already sends out proper HTTP headers to allow static files, such as JavaScript to be cached on the client.

What you have to make sure, is that you’re able to bust the cache. Either use expiration headers, or add a version indicator to the URL of the file. Next time you deploy, increase that number to make it a new URL.

9. Use a Content Delivery Network – CDN

If you have lots of traffic, from all over the world. You can benefit from hosting your JavaScript files on a Content Delivery Network. With all the new cloud hosting companies out there, this has become exceptionally cheap.

For jQuery and other common libraries, you can also use the CDN hosted files provided by jQuery, Google or Microsoft.

10. Write JavaScript Unit Tests

Some people would probably say this should not be the last thing to do. But I think you need all the low-hanging fruits, that you can accomplish before you start dramatically changing the way you go about writing JavaScript. And unit testing JavaScript is going to do that.

There are several good unit testing libraries for JavaScript. The more popular are QUnit and Jasmine.

Conclusion

There’s a lot of things you can do to re-structure and get control of JavaScript. One thing is for sure. If you do nothing, things will get messy.

This was my take on what can be done, things I’ve done in the past with great success.

What do you think is missing, what have you done that greatly improved the quality of your JavaScript code-base?

JavaScript Bundling Issues When Using Unfinished Closures

We all know it’s a good idea to bundle JavaScript files into as few script includes as possible to minimize HTTP request.

And – we all know you should write your code inside closures, to avoid the biggest problem of JavaScript: its dependence on global variables!

But what happens when those two things don’t work together?

For me, they didn’t play nice with each other today. Whenever I bundled my JavaScript files i got an Uncaught TypeError: undefined is not a function.

Consider this code:

/****** a-file.js ******/
!function($) {
  // Code here
}(window.jQuery)

/****** another-file.js ******/
(function ($) {
  $("#hello").text("World!");
})(window.jQuery);​

The error occurred on the first line, inside the closure in another-file.js. Take a look at this jsFiddle.

Since the result of the first closure is true, the above code will evaluate as this:

/****** a-file.js ******/
true

/****** another-file.js ******/
(function ($) {
  $("#hello").text("World!");
})(window.jQuery);​

The only thing missing, is a semicolon to finish off the first closure (updated, and working jsFiddle):

/****** a-file.js ******/
!function($) {
  // Code here
}(window.jQuery);

/****** another-file.js ******/
(function ($) {
  $("#hello").text("World!");   
})(window.jQuery);​

Now, this is a trivial thing to get right, if you were only dealing with your own code base. But with loads of plugins, external libraries and such – you can only pray for the best!

In my case, the script that were causing the error was Twitter Bootstrap scripts. They were all missing the semi-colon in version 2.0, the issue was submitted a month ago, and later fixed

 

Making your ASP.NET Global Resource files work in JavaScript. IntelliSense included!

Any modern web application needs localization! You simply can’t ignore the huge amounts of people who doesn’t speak your language, or whose native language is different from yours.

You’re probably using resource files (.resx) in .NET, but how do you go about getting values from your resource files in JavaScript?

Rick Strahl wrote a great blog post about an HttpHandler that serves the content of your resource files in JavaScript. You basically add a script tag to your page that points to the HttpHandler, and the HttpHandler will produce the resources in JavaScript as an object with properties on it, like this:

[code lang="js"]var localRes = {
AreYouSureYouWantToRemoveValue: "Sind Sie sicher dass Sie diesen Wert l\u00F6schen wollen?",
BackupComplete: "Der Backup f\u00FChrte erfolgreich durch",
BackupFailed: "Der Backup konnte nicht durchgef\u00FChrt werden",
BackupNotification: "Diese Operation macht einen Backup von der Lokalisationtabelle. \nM\u00F6chten Sie fortfahren?",
Close: "Schliessen",
FeatureDisabled: "Diese Funktion ist nicht vorhanden im on-line Demo ",
InvalidFileUploaded: "Unzul\u00E4ssige Akten Format hochgeladen.",
InvalidResourceId: "Unzul\u00E4ssige ResourceId",
Loading: "Laden",
LocalizationTableCreated: "Lokalisations Akte wurde erfolgreich erstellt.",
LocalizationTableNotCreated: "Die Localizations Akte konnte nicht erstellt werden."
};[/code]

This is awesome! Now you can access your resource files from JavaScript. Though, I see a single improvement to be made. The thing I don’t like about the HttpHandler approach, is that you don’t get IntelliSense support in Visual Studio. So you have to browse your resource file and copy & paste the resource key to your JavaScript files in order for this to work.

Generate static JavaScript files on Post-build

Instead of generating dynamic files at runtime, I prefer to generate static JavaScript files and then dynamically include the file of the current language on my pages. I do this by calling a Console Application I’ve written on the Post-build event of my ASP.NET (MVC) project, which you can set in the property pages of your project (By the way, did you know that you can open property pages of a project by double clicking the default Properties folder?):

image

What my JavascriptResxGenerator App does, is quite messy. But the essence of the App is, of course, to take a single (or several) .resx files and do the following:

1. Loop through all keys.

2. Make sure the key is not a JavaScript reserved word.

3. Add the key and value to a dictionary (in JavaScript).

4. Write the file.

And for the default culture I generate a –vsdoc file, that I can use for Visual Studio IntelliSense.

Using the JavaScript Resx Generator App

My App supports a single file approach, and directory approach.

Single file: JavascriptResxGenerator.exe C:\Folder\Text.resx C:\Output C:\Output\VsDoc MyApp.Namespace.Resources

Directory: JavascriptResxGenerator.exe C:\Folder C:\Output C:\Output\VsDoc MyApp.Namespace.Resources

The MyApp.Namespace.Resources value, is the namespace your resource dictionary will get enclosed in.

image

Embedding the file on your pages

To include the JavaScript resource file in your page, you simply add a script include tag that points to the correct language. The App will respect the region token used in your Resx files. So if you have a file called Text.da.resx, the JavaScript file generated will include .da.resx at the end. It’s then up to you to add the correct logic to keep hold of the current language and specify the correct region token in order to include the correct JavaScript resource file.

Download

You can download the App here, as a ZIP file.