JavaScript

Client server event aggregation with Angular

I dont fancy Angular much, its slow and Knockout with its MVVM approach is much cleaner, and faster since computed and observables only mutate and change view state when they actually need to (That will change with Angular 2.0). Anyway, my current customer sports Angular and then you just have to form inline ­čśÇ We needed immediate update and you know I love event aggregation and probably know that I have a library for it, you can read more about it here!

I created a little wrapper for the the vanilla javascript client, install it using nuget
Install-Package SignalR.EventAggregatorProxy.Client.Angular

Basically it works by extending the Angular $rootScope and adds a eventAggregator function to all scopes. The eventAggregator function resolves the scope and then creates a closure with two methods, subscribe and publish. You can now listen to a event like (Serverside or client side event).

$scope.eventAggregator().subscribe(MyApp.MyEvent, onEvent);

(more…)

Advertisements

Seperate KO View formating and ViewModel state

A normal scenario with Knockout is that you want date and number observables to be formatted to the current culture of the client, this is easily implemented in a Knockout extender, something like.

ko.extenders.numeric = function(observable, options) {
    var textValue = null;
    return ko.computed({
        write: function(value) {
            textValue = value;
            var parsed = Number.parseFloat(value);
            if(!isNaN(parsed)) {
                observable(parsed);
            } else {
                observable(null);
            }
        },
        read: function() {
            var value = observable();
            if(value == null) {
                return textValue;
            }

            return value.toLocaleString(); //This  can be replaced with for example the Globalize plugin 
        }
    });
};

Use it like

this.amount = ko.observable().extend({ numeric: true });

The problem with this approach is that the ViewModel will no longer work against numbers it will work against formatted strings, so this.amount() will return a string instead of a number. This is very bad practice in a View/ViewModel seperation stand point. (more…)

Wrap client side code in a Web Forms Control

I’m currently between assignments and in the meantime I’m helping fellow colleagues with a Web Forms system. They needed a Combobox for a requirement and after some googling I found out that there is none for free which suits their needs. I have created a Knockout enabled combo called Knockout.Combobox. I decided to take this client side combobox and wrap it in a Web Forms Control.
(more…)

Client – server event aggregation with SignalR

Event aggregation is really a pattern i like, there is something elegant about firing events and subscribers can listen to them without knowing who fired them. This creates decoupled domains both in backends and frontends. At my latest customer we saw an increasing demand for pub / sub and immediate update. We fired events on the backend event bus and in the frontend we had SignalR Hubs that picked up the events and forwarded them to the clients. This caused duplicated and similar code both on the client and on the web server. I decided to create an abstraction layer between SignalR and the event aggregator. The result is a library called SignalR.EventAggregatorProxy

(more…)

Convention based MVVM with Knockout

One of my most popular Open source projects, FreePIE, is a WPF application and it utilizes a library called Caliburn.Micro. The main idea for that library is to minimize the use of explicit declared bindings and use conventions to implicit bind to the ViewModel under the hood. As an example, if you have a button called Save and a method called Save on your VM, Caliburn.Micro will make sure these are bound.
This is a welcomed tool since XAML bindings are, to say the least, verbose.

Bindings get even more verbose in the Knockout world because of the fact that you can write inline JavaScript in the bindings, fact is the entire data-bind attribute is inline JavaScript that is executed by Knockout. I’ve seen that bindings like these and worse are common out there.

<button data-bind="enable: errors().length === 0">Save</button>

I started to write a Convention based library called Knockout.BindingConventions a year ago and I added support for Knockout 3.0 a while back. Even though the library isn’t new I thought I could write about it, it’s a good way to get to know the inner working of Knockout and also convention over configuration. (more…)

Typed javascript contracts using T4 Templates

A big problem with AJAX enabled JavaScript sites are the contract between server and client. A common “contract” is just to use jQuery.ajax with an inline declared URL and some parameters. A big problem with this approach is the fact that there is no real contract between client and server. Another problem is the fact that, as the site grows, so will your list of web methods and URL’s to go with them.

CQRS is winning more ground these days, and it has several advantages over the more classic ways of communication. One of the biggest is that there are no more god service classes with hundreds of methods and URL’s. Most implementations I have seen with CQRS in web projects only leverage CQRS between the server-side web and the message bus/backend. The client still communicates with a standard web method that just redirects the calls to the message bus. Why not leverage the contract safety and other perks of CQRS all the way from the client to message bus?

In the WCF-world we can share a common contract assembly that holds all command and queries, this is not the case with JavaScript. At my latest customer project I came up with the idea to use a T4 template to render all the commands and queries into a JavaScript file. You will even benefit from code completion in Visual Studio, at least if you use Resharper 6 or later.

First we need to create the T4 template. We can not use reflection to get the Command and query types because a T4 template is executed at design time not runtime or compile time. Instead we have to use the tools found in the EnvDTE┬ánamespace to retrieve all the projects of the solution and their types. The problem with EnvDTE is that it’s a major pain to work with, but don’t worry, there are remedies out there. From the extension manager in VS install the Tangible T4 Editor, it comes with a T4 template with helper methods for the EnvDTE tools.

Include the Visual Studio Automation Helper from the Tangible editor.

Image

It comes with a helper class called VisualStudioHelper with a bunch of helpful methods to retrieve info from a project and its types. Even though VisualStudioHelper is very helpful we still need some custom helper methods written. You need to write a method that gets all types that inherit a specific base class or resides in a special namespace or any other convenient convention that fits your project . It should look something like this.

public IEnumerable<CodeClass> GetSubClasses(string baseClass, Project project)
{
	return VisualStudioHelper		
		.CodeModel
		.GetAllCodeElementsOfType(project.CodeModel.CodeElements, EnvDTE.vsCMElement.vsCMElementClass, false)
		.Cast<CodeClass>()
		.Where(c => GetInheritance(c).Any(b => b.FullName == baseClass) && !c.IsAbstract)
		.ToList(); 
}

public IEnumerable<CodeClass> GetInheritance(CodeClass @class) 
{
	foreach(CodeClass @base in @class.Bases) 
	{
		yield return @base;
		foreach(var sub in GetInheritance(@base)) 
			yield return sub;
	}
}

Now we can get all DTO contract types for a specific project like this

var project = VisualStudioHelper.GetProject("MyApp.Core.Contracts");
var contracts = GetSubClasses("MyApp.Core.Contracts.Commands.Command", project)
	.Concat(GetSubClasses("MyApp.Core.Contracts.Queries.Query", project));

After that its just a matter of rendering the JavaScript version of the types, you have to be very specific about how you declare your objects for VS to be able to pick them up with code completion. And at the same time you must ensure that you do not overwrite any existing object closures.

First we create object closures for all namespaces and make sure they do not overwrite any existing closures.

window.MyApp = (window.MyApp || {});
window.MyApp.Core = (window.MyApp.Core || {});
window.MyApp.Core.Contracts = (window.MyApp.Core.Contracts || {});
window.MyApp.Core.Contracts.Commands = (window.MyApp.Core.Contracts.Commands || {});

Then we create each Type as a javascript function (Constructor).

window.MyApp.Core.Contracts.Commands.FooCommand = function(bar) {
    this.bar = bar;
};

I also add the fully qualified name to the object like this

window.MyApp.Core.Contracts.Commands.FooCommand.type = "MyApp.Core.Contracts.Commands.FooCommand";

It’s later used when sending a DTO to the server. Above JavaScript is rendered like this. Helper methods excluded, you can checkout the full example at Github.

foreach(var part in BuildNamespace(contracts)) {
	#>	<#= part #>
<#
}

foreach(var contract in contracts) {
		#>	
	<#

    var properties = GetProperties(contract).Select(p => CamelCased(p.Name)).ToList();
    var args = string.Join(", ", properties);

    #>

    window.<#= contract.FullName #> = function(<#= args #>) {<#
    foreach(var property in properties) {#>

        this.<#= property #> = <#= property #>;<#
    }
	#>

    };
    window.<#= contract.FullName #>.type = "<#= contract.FullName #>";
<#
}
#>

We also need some client code that can send the DTO’s, sadly the .NET WebApi that we use for this particular project does not support dynamic C# objects from arbitrary JSON objects so we had to send the DTO data as a string (Side note, vanilla JSON.NET that WebApi utilizes does support dynamic objects).

function buildContract(contract) {
	return { type: contract.constructor.type, data: ko.toJSON(contract) };
}
var url = "api/commandQuery";
MyApp.cqrs = {
	sendQuery: function(query, callback) {
		MyApp.utils.get(url, buildContract(query), callback);
	},
	sendCommand: function(command) {
		MyApp.utils.post(url, buildContract(command));
	}
};

You send a command or query like this.

MyApp.cqrs.sendCommand(new MyApp.Core.Contracts.Commands.FooCommand("bar"));

The server needs to create static typed C# objects instances, to do this we need to get a little creative with JSON.NET. First we declare a Data contract that WebApi is capable of deserialize to.

public class Contract
{
    public string Type { get; set; }
    public string Data { get; set; }
}

Then we need to create a way of decoding that data into a real object instance of the correct static type. We use some JSON.Net magic for this.

private TDto CreateDto<TDto>(Contract contract) where TDto : class
{
    var type = typeof(Query).Assembly.GetType(contract.Type);
    var jObject = JObject.Parse(contract.Data);
    var dto = jObject.ToObject(type);

    return dto as TDto;
}

We get the Type object instance from the type string sent from client then we use JSON.NET to first create e dynamic object from the string data and then we use the ToObject method that uses reflection to create a static typed version of the dynamic object. We use the above method from our WebApi method like.

public QueryResult Get([FromUri]Contract contract)
{
    var query = CreateDto(contract);
    return client.SendQuery(query);
}

A fully featured example of this technique can be found here