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!

Creating mocks with Breeze.js

Breeze.js is a powerful library you can leverage in your Single Page Applications.  It plays nicely with all other technologies, and is designed to provide rich client-side data.  You can easily it with your application, regardless of the tech stack.  Don’t believe me?  Prove otherwise.  The authors of Breeze.js have certainly shown you can in their samples – – (Side note: check out the ESPN sample, whoever made it is a genius)

Mocks –

Most applications have need for mocks.  Mocks can be especially powerful when you are building out the front-end and the back-end isn’t entirely ready yet.  You can also use them for writing unit tests against data without having to populate from the server.  I won’t get into testing in this post because there are so many ways to test and the tests can be very opinionated.

The only requirement for mocks is that you need to have your metadata in place first, either from the server or as the Breeze.js authors mention in the docs you can also get a snapshot of your metadata and pass it in when mocking. This is a great way to iterate and update your models. (Reference –

Example –

function loadMocks (manager) {
    var personMockOne = manager.createEntity('Person', { id: 1, firstName: 'John', lastName: 'Smith' });
    var companyMockOne = manager.createEntity('Company', { id: 1, name: 'Acme Inc.' });

That’s it! We now have mocks we can run our tests against or build out our pages. Calling loadMocks() and passing in our manager will add the mocks to our entity collection and we can start testing. We pass in the manager to keep our function anonymous, and in the above example I am adding the employee mock to the company’s employees collection, but we could just as easily create the company and then set the company property on the person to companyMockOne. Example –

var companyMockOne = manager.createEntity('Company', { id: 1, name: 'Acme Inc.' });
var personMockOne = manager.createEntity('Person', { id: 1, firstName: 'John', lastName: 'Smith', company: companyMockOne });

You will notice when using this technique that the entityState of the entities are added. If you have logic in your page related to saving or cancelling changes, this could potentially trigger your UI to think the mocks need to be saved. We can easily get around that as well by calling acceptChanges() on the entityAspect of the entity. Example –

var companyMockOne = manager.createEntity('Company', { id: 1, name: 'Acme Inc.' });

This will let Breeze know that you are comfortable with the changes made to the company and they do not need to be persisted to back to the database. While you could also chain the entityAspect.acceptChanges() onto the end of the createEntity method, beware that this will no longer return the entity.

var companyMockOne = manager.createEntity('Company', { id: 1, name: 'Acme Inc.' }).entityAspect.acceptChanges();
// The next line will not console log our entity

I often use this method for create enumerations as well that aren’t strictly passed down from a server. This can be especially useful when using someone else’s API where they aren’t exposing all of the data you need. Last Example –

manager.createEntity('Priority', { id: 1, name: 'Severe', imageSource: 'severe.jpg' }).entityAspect.acceptChanges();

This can be especially useful if you are re-using the enum all over your application.

I hope you find this useful, please leave any feedback below, especially if you see any errors. Direct any trouble-shooting questions to, and check out the Breeze.js UserVoice for feedback or feature requests.

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.