Building the first SPA JavaScript game using Breeze.js and Durandal.js

So in the wild everyone is teaching you how to build a new enterprise application using single page application (SPA) architecture and libraries like Breeze.js.  I am a huge proponent of Breeze.js and what it can do for your application, but that is a different subject.  What I wanted to do now was share a project I am working on / building for a game contest that interests me.

Richard Garriott, the creator of Ultima Online, posted this challenge for developers to re-create a 1977 game called DND1 that was originally written in BASIC for a TeleType machine.  I started to try to figure it out and somewhere along the lines realized this would be fun to do in a single page application to show how powerful things like Breeze.js and Durandal.js can be for any purpose.

Check out the github here –

Check out the working version of the game here –

Let me know what you think in the comments!


Best parts about Durandal

I wanted to start a quick series dedicated to what makes Durandal so powerful to yield.

Part 1 – 

The Compose binding

With Durandal, you can dynamically load views and AMD modules directly from the DOM.  Why is this important?

  1. You can separate your views and modules into the smallest bits of (re-usable) code needed.
  2. Render your content more dynamically.
  3. You can easily instantiate and show either Singleton objects or Constructors.  (wait what?)

Separating your code

Imagine you want to create ‘n’ number of widgets that are in charge of their own visibility, data-fetching, and data-binding.  Easy.  Using the compose binding with a foreach, you can instantiate the modules in your view model and use the DOM to render them.

View –

<ul data-bind="foreach: widgets">
     <li data-bind="compose: widgetPath"></li>

View Model –

define([], function () {
    var widgets = ko.observableArray();
    function initializeViewModel() {
        widgets.push(new Widget('Compose a widget module', 'viewmodels/exampleone'));
        widgets.push(new Widget('Compose a widget view only', 'exampletwo'));
    function activate() {
    function Widget(title, path) {
        var self = this;
        self.Title = title;
        self.widgetPath = path;

What did we just do?

1. When we initiated the view model, we added two widgets into an observable array containing widgets.
2. The first widget is a path to a view model, which Durandal finds an associated view for and properly recognizes as part of a module.
3. The second widget is a path to a view, with no corresponding view model.

Whats interesting to note here is that in the first widget with a corresponding view model, Durandal helps us by creating a context around that view that is bound to the view model. This means if we reference something in the view model that Knockout and Durandal bind any related view elements to that instance of the view model. This is most ideal when not using singletons, as the every instance of a singleton will be bound to the same context.

In the second widget we are simply binding to the current context, which in this case would be the widget.  This is derived from the foreach binding that the widget is nested inside of, so you could easily bind to the title property or you could also reference the parent context using the Knockout $parent reference.

The reason $parent would not work in the first example is that the new context does not directly know who the parent is.  What if we wanted it to?  That’s easy as well, using activationData

Activation Data –

Using the activationData option of the compose binding, we can inject data or even context into the composed view model.  This is an excellent way of injecting dependency, and I could go on for hours on the various ways you can use this in your application, but let’s keep it simple and show an example.

Let’s bind our view up to widgets using Knockout’s containerless binding –

<!-- ko foreach: widgets -->
    <!-- ko compose: { model: widgetPath, activationData: { data: $data } } -->
    <!-- /ko -->
<!-- /ko -->

You’ll notice that I passing an object into the compose binding that contains a model and activationData, which contains an object of it’s own. You can read more on the Durandal website on the various parameters ( but basically the model is declaring that at that path, there is a view model to use for binding. Durandal automatically finds the corresponding view, and then injects our activationData into the view model. To intercept it, you only need to have a parameter in your activate method of the widget. Notice I am injecting $data, which basically just injects the current context into the view model. You could just as easily inject strings, observables, and even parent contexts.

Grabbing the data in our widget’s view model –

define([], function () {
    var thisContext = ko.observable();
    function activate(activationData) {
        // Set thisContext equal to the injected data
    function Widget(title, path) {
        var self = this;
        self.Title = title;
        self.widgetPath = path;

Now you can bind thisContext in the view however you want. A solid strategy is to use the with binding in your view that is set to thisContext, that way if for some reason your view model is instantiated without data it will just appear empty as opposed to breaking your bindings.

That’s it! Feel free to leave comments if you notice any problems or have any suggestions or questions. If you have any Durandal questions please direct them to or the Durandal.js Google Group, where the active community will help resolve them.

Consuming an API is a Breeze

Having trouble getting your new JavaScript libraries to play together nicely?  Want to see how you can use Breeze.js and Knockout.js to consume any API, ever, since the history of your browser?  Then look no further…


Checking out new JavaScript libraries and Frameworks can be scary.  Do you have a back-end already in place and just want to see what you can do on the front-end with Breeze.js and Knockout.js?  This sample / walk-thru is served only with an API, ESPN’s Developer API to be specific.  The only thing we do on the server here is server up our view from a Durandal.js starter app.  I choose Durandal.js because it is an extremely fast way to get a new project up in running, and provides a working app that needs only a few minutes to transform into an app of your own.

You can grab a working sample here of the finished code – (Note: this project uses NuGet package restore – read more about it here if you are unfamiliar

Breeze.js is an open-source JavaScript library from the established and well-respected team at IdeaBlade aimed at providing rich client-side data to your JavaScript apps.

  • Handles caching your data in the browser
  • Keeps track of changes to your JavaScript entities (and supports canceling those changes easily!)
  • Provides Linq-style queries in JavaScript

Knockout.js is an open-source JavaScript library created by Steve Sanderson to provide data binding all the way back to IE 6 (!!!!!)

  • Utilizes the MVVM pattern
  • Is an easy bolt-on to any project (Knockout is only concerned with binding data and keeping your view up-to-date)
  • Plug-ins are available to tackle any problem you have, and scale easily

Summary – 

The objective of this walk-thru is to help new to intermediate level JavaScript developers understand Breeze.js better and get a glimpse of the functionality when coupled with Knockout.js.  We will create a new project, add basic dependencies, set up Breeze to use with any API, create a JSON results adapter to map complex data structures, and bind our data to the view.

This is an open-source sample so if you see a problem feel free to make a pull request.  If you see a typo or something that just isn’t right feel free to leave a comment, or even send me a message either on here or on GitHub – pw kad

Technologies used –

Breeze.js –

Knockout.js –

Durandal.js – – (Use the starter kit to get a JavaScript app up and running extremely fast)

Twitter Bootstrap –

Getting Started – 

As a note, I use Visual Studio 2012 as my text editor for familiarity and ease-of-use. Let me know if you see any errors or have any helpful hints in the comments.

Create our new project – 

The Durandal Starter Kit is available at as a free download and also via as the SPA template (Note: Durandal 2.0 is now released, this project currently uses Durandal 1.2)

Open VS2012 and create a new ASP.NET MVC 4 application.  You can either create an Empty project and use NuGet to get the Durandal Starter Kit or install the template listed above and use Durandal SPA Project from the available templates window.

Creating a Durandal Starter Kit project

Creating a Durandal Starter Kit project’

We need to add a directory to our ‘App’ folder for the services we will use – App > services - This is where we will place our JavaScript files for getting data, creating the models, and any other JS files that are not view models.

Adding dependencies – 

Right click on our newly created project and choose Manage nuget packages… this will allow us to add our dependencies quickly and easily.

Choose the online option on the left of the pop-up to search online for available packages and in the top right search box type breeze to search for Breeze.js.  Install the Breeze for ASP.NET Web Api Projects package.  This package will add Breeze.js to the scripts folder, but it will also add some server-side stuff that we won’t be using.  (Basically if we were creating this project to serve up data as well as consume it we would need this additional library to make life easier, but since we will only be consuming the API we don’t need to worry about it)

Feel free to take a look in the scripts folder and check out our new dependencies.  Q.js is a promises library that Breeze uses to perform Asynchronous operations, such as querying.  If Sammy.js is in there, it was provided by our Durandal Starter Kit to help with routing and navigation (Note: Durandal 2.0 does not use the router plug-in including Sammy.js for routing nor navigation)

The only thing in the Controllers directory should be our Durandal controller, which will serve up our initial view.  The only thing in the Views folder are the splash page Durandal uses when loading up and an Index.cshtml file to host our Single Page App on.

Adding services – 

Inside of our services directory we need to add three JavaScript files (modules) –

First, let’s add our datacontext.js to the App/services folder.  This is requiring two services we haven’t finished setting up yet, (model and jsonResultsAdapter) so this won’t yet compile properly.

define(['services/model', 'services/jsonResultsAdapter'],
    function (model, jsonResultsAdapter) {


Note on AMD (Asynchronous Module Definition) –

The define() statement defines the beginning of a module and is used to inject dependencies.  In this case we are using system/durandal and log system messages, so we require it and let our module know it can call it by using system

We will be using the model and jsonResultsAdapter in this module so we need to require them. Let’s add some basic functions to our datacontext

        var EntityQuery = breeze.EntityQuery;
        function returnResults(data) {
            return data.results;
        var datacontext = {
        return datacontext;
        function getLocal(resource, entityType, ordering) {
            var query = EntityQuery.from(resource)
            return manager.executeQueryLocally(query);
        function queryFailed(error) {
            var msg = 'Error retrieving data. ' + error.message;

The EntityQuery variable will negate our need to call breeze.EntityQuery for each query we write.

The datacontext object we are creating is used to expose our functions to other modules that require it when it is returned.

getLocal is just a helper function to get local instances of an entity.

queryFailed is just a helper function logging errors in the console.

Setting up Breeze in our DataContext – 

We need to set up Breeze inside our datacontext

        var serviceName = "";
        var ds = new breeze.DataService({
            serviceName: serviceName,
            hasServerMetadata: false,
            useJsonp: true,
            jsonResultsAdapter: jsonResultsAdapter
        function configureBreezeManager() {
            var mgr = new breeze.EntityManager({ dataService: ds });
            return mgr;
        var manager = configureBreezeManager();
        var metadataStore = manager.metadataStore;

This sets up a data-service, letting Breeze know that we don’t have any meta data available and will have to make our own and also let’s Breeze know we are going to use a custom jsonResultsAdapter.  We haven’t yet created it, but it is being required at the top of our datacontext in our define statement so it is available to us inside of it.

Next we need to create a model.js in our App/services folder –

define(['configuration'], function (config) {
    var DT = breeze.DataType;
    var model = {
        initialize: initialize
    return model;

As you can see, we are revealing a function called initialize that initializes our entity models. We could have put this into our datacontext module but in the interest of the separation of concerns principle we want to keep this module separate.

    function initialize(metadataStore) {
            shortName: "NewsItem",
            namespace: "ESPN",
            dataProperties: {
                id: { dataType: "Int64", isPartOfKey: true },
                teamId: { dataType: "Int64" },
                headline: { dataType: "String" },
                description: { dataType: "String" },
                source: { dataType: "String" },
                imageSource: { dataType: "String" },
                imageCaption: { dataType: "String" },
                imageCredit: { dataType: "String" },
                link: { dataType: "String" }
            navigationProperties: {
                team: {
                    entityTypeName: "Team", isScalar: true,
                    associationName: "Team_NewsItems", foreignKeyNames: ["teamId"]
            shortName: "Team",
            namespace: "ESPN",
            dataProperties: {
                id: { dataType: "Int64", isPartOfKey: true },
                location: { dataType: "String" },
                name: { dataType: "String" },
                abbreviation: { dataType: "String" },
                color: { dataType: "String" }
            navigationProperties: {
                newsItems: {
                    entityTypeName: "NewsItem", isScalar: false,
                    associationName: "Team_NewsItems"
            'Team', null, teamInitializer);
        function teamInitializer(team) {
            team.fullName = ko.computed(function () {
                var loc = team.location();
                var name =;
                return loc + ' ' + name;
            team.showNews = ko.observable(false);

If you remember earlier in our datacontext we passed the metadataStore into the model.initialize() function. model.initialize(manager.metadataStore);. In the model we are adding types ‘Team’ and ‘NewsItem’. These entities have navigation properties linking them, which we set up with an association. This will allow us to easily bind the data in the view, and will remove the need to make additional calls to the server.

Finally, we want to register a custom property on the Team called ‘fullName’ which is a computed observable. We will use this in the view to represent a team’s location and name (ie. Texas Rangers) We are also setting an observable called showNews that we will use to flag whether the team’s news is being shown. Every time an entity is pulled in from the server or created these functions will be executed.

Now let’s set up our API calls in the datacontext

        var myAPIKEY = "qubdkem5nhuctxtxghkx32nm";
        var getTeams = function (teamsObservable, forceRemote) {
            if (!forceRemote) {
                var p = getLocal('Teams', 'Team', 'id');
                if (p.length > 0) {
                    return Q.resolve();
            var parameters = makeParameters();
            var query = breeze.EntityQuery
            return manager.executeQuery(query).then(querySucceeded).fail(queryFailed);
            function querySucceeded(data) {
                var s = data.results;
                return teamsObservable(s);
        var getTeamNews = function (team) {            
            var parameters = makeParameters();
            var query = breeze.EntityQuery
                .from("teams/" + + "/news")
            return manager.executeQuery(query).then(querySucceeded).fail(queryFailed);
            function querySucceeded(data) {
                var s = data.results;
                var tempObs = ko.observableArray(s);
                // Since the news item has multiple categories and can be for multiple teams
                // we will set the team explicitly to the team we are searching for.
                // We could set it to each team, but this is a simple example.
                ko.utils.arrayForEach(tempObs(), function (newsitem) {
                return true;
        function makeParameters(addlParameters) {
            var parameters = {
                apikey: myAPIKEY
            return breeze.core.extend(parameters, addlParameters);
        function returnResults(data) {
            return data.results;

There is a lot going on here so let’s get down into more detail –

myAPIKEY is an API key provided by ESPN.  You can register for your own at

getTeams and getTeamNews are two functions that perform Breeze EntityQuery’s.  You can learn a lot more about structuring these queries on Breeze’s website, and I won’t cover exactly how they work here (would make this walk-thru much longer) but understand that these queries are structured to check the local cache for entities, and if there are none they will go hit the API.

makeParameters is an internal helper function that creates parameters.  The ESPN developer API requires a key to be passed, and we are extending any additional parameters passed in.  This will make our API call look something like this –[apiKey will show up here]

Finally, there is a returnResults function that we will use to return the data.results from the callback.

We need to expose those functions to any other module that is requiring the datacontext, so adjust the object we are returning in our datacontext.

        var datacontext = {
            getTeams: getTeams,
            getTeamNews: getTeamNews
        return datacontext;

Now that our datacontext is ready to go, we need to set up our jsonResultsAdapter.js

define([], new breeze.JsonResultsAdapter({
    name: "ESPN",
    extractResults: function (data) {
        var results = data.results;
        if (!results) throw new Error("Unable to resolve 'results' property");
        return results && (results.headlines);
    visitNode: function (node, mappingContext, nodeContext) {
        if (node.headline) {
            if (node.images.length > 0) { 
                node.imageSource = node.images[0].url;
                node.imageCaption = node.images[0].caption;
                node.imageCredit = node.images[0].credit;
            else {
                node.imageSource = '../content/images/blank_image.png';
                node.imageCaption = 'none';
                node.imageCredit = 'no credit';
   = node.links.web.href;
            return { entityType: "NewsItem" };

This is a custom adapter we register in our datacontext to map the results from a complex JSON structure.  You can read more about how it works in the Breeze docs, but here is a basic breakdown –

name assigns a namespace.  If you remember earlier when we created the entity types in our model we assigned them to a namespace.

extractResults makes sure that the data returned has a results property and then checks to see if there is a headlines property.  If so, we create entities out of the results.  The reason we check for a headlines is because it is a unique property on the news objects being returned, so we know that if a result has a property headlines it should be mapped to a NewsItem.  When a news item is created we also need to map some of it’s properties.

Alright, that was a lot of JavaScript.  Let’s see some results –

Note – The below portion of this walk-thru doesn’t go into a lot of detail yet.  Give me a few days and I can explain it in more detail.

Delete the code inside your home.html in your App/views folder. Replace it with the below HTML –

<h3 class="teams-header">Team News - <img src="" /></h3>
<div class="accordion" id="sports-accordion" data-bind="foreach: teams">
  <div class="accordion-group">
    <div class="accordion-heading" data-bind="style: { backgroundColor: '#' + color() }" >
        <a class="accordion-toggle team-brief" data-toggle="collapse" data-parent="#sports-accordion" 
            data-bind="attr: { href: '#' + abbreviation() }" >
            <p><span data-bind="text: abbreviation"></span> - <span data-bind="text: fullName"></span></p>
    <!-- ko if: showNews() === true -->
    <h5 data-bind="visible: newsItems().length === 0">Fetching news...</h5>
    <div data-bind="attr: { id: abbreviation }" class="accordion-body collapse in">
      <div class="accordion-inner">
        <ul class="media-list" data-bind="foreach: newsItems">
            <li class="media">
                <a class="pull-left" data-bind="attr: { href: link }">
                    <img class="media-object" data-bind="attr: { src: imageSource(), title: imageCredit }" />
                <div class="media-body">
                    <h4 class="media-heading" data-bind="text: headline"></h4>
                        <p data-bind="text: description"></p>
                        <small>from <cite title="Source" data-bind="text: source"></cite></small>
    <!-- /ko -->

This is a Twitter Bootstrap accordion bound to our Knockout data.

Now replace all of the home.js code in our App/viewmodels folder with the below –

define(['services/datacontext', 'viewmodels/shell'], function (datacontext, shell) {
    var teams = ko.observableArray();
    var bindEventToList = function (rootSelector, selector, callback, eventName) {
        var eName = eventName || 'click';
        $(rootSelector).on(eName, selector, function () {
            var team = ko.dataFor(this);
            return false;
    var toggleTeamNews = function (team) {
        if (team.showNews() === true) { team.showNews(false); }
        else {
            if (team.newsItems().length === 0) {
    var viewAttached = function (view) {
        bindEventToList(view, '.team-brief', toggleTeamNews);
    var initLookups = function () {
    function queryFailed(error) {
        console.log(error.message + " - Query failed; please try it again.");
    var activate = function () {
        return true;
    var home = {
        activate: activate,
        teams: teams,
        viewAttached: viewAttached,
        shell: shell
    return home;

That’s it! Run our app and you will see a list of MLB teams, with the names on top of their team color returned from the server. Clicking on any of the teams will go fetch their news, and once we have fetched it Breeze is caching the NewsItem’s so we can hide or display them as we see fit, without having to hit the server again.