Greater Heights Ltd

.net Software Consultants

Grumpy DJ?

I am a big fan of React an even bigger fan of Redux. I also love the Solid Steel Podcast quality mixes by different DJs every week, what's not to love. Well apparently getting your mix picked by Solid Steel for their weekly podcast is not to love. Follow the link and take a look, every mix has a picture of the chosen DJ, most seem somewhat unhappy or are they? How to tell…….

By over engineering it that how! So I built this little web application using React, Redux, Typescript and the amazing Microsoft Emotion Api.

What does it do? Well using the Mixcloud API it fetches all the Solid Steel Podcast metadata and sends each picture to the Emotion API for analysis.  Lets have a look at the results.

 

As we can see HNNY seems rather neutral,

2016-06-03

 

Whereas Jungle, ah well this isn't really helping my case.

2016-06-03 (1)

 

Lets take a look at a few more

Fracture? not looking too cheery.

2016-06-03 (2)

 

Rob Da Bank? not unhappy.

2016-06-03 (3)

 

JD Twich? now that's better, looking quite moody, but neutral apparently.

2016-06-03 (5)

 

Paeleh? neutral apparently but I detect a hint of a smile creeping in.

2016-06-03 (4)

 

So what have we proved here?

  1. react, redux , typescript, webpack are amazing tools for building web apps
  2. Some DJs don't seem very happy about getting mixes onto Solid Steel.
  3. The Microsoft Emotion API is very clever.
  4. I may have too much time on my hands.

Well the codes all here up on my Git repository. You will need to get your own Microsoft Emotion API key to test it but that's pretty quick and easy to do, just follow the link and click the ‘Get Started’ button. When you have your generated key search the code for the string [your key here]] and replace with your key.

Kendo bootstrap grid example

Just posted a little example demonstrating using a Kendo UI grid with Web API 2 ODATA controllers and a custom bootstrap modal popup instead of the default kendo popup.

Code available from my git repository. I will be posting a full article about this code soon.

Remove magic strings from Breeze.js queries with T4 and typescript.

If you are familiar with Breeze.js you will be familiar with the following style of statement.
var manager = new breeze.EntityManager('api/northwind');

var query = new breeze.EntityQuery()
    .from("Employees");
manager.executeQuery(query).then(function(data){
    ko.applyBindings(data);
}).fail(function(e) {
    alert(e);  
});

There are a number of problems with this statement.

  1. How do we know that we have an entity set called “Employees”.
  2. What if the developer spells it wrong?
  3. How do we keep this in line with our EntityFramework entities?
To solve both these problems I have written a T4 template to generate the typescript module that exports a class for each entity in our EntityFramework context. I cannot claim the contents of the template are entirely my work the code for the FindClasses function comes from this stackoverflow post.
<#@ template language="C#" debug="false" hostspecific="true" #>
<#@ output extension=".ts" #>
<#@ assembly name="System" #>
<#@ assembly name="System.Core" #>
<#@ assembly name="System.Data.Entity" #>
<#@ assembly name="EnvDTE" #>
<#@ import namespace="EnvDTE" #>
<#@ import namespace="System" #>
<#@ import namespace="System.Collections" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Reflection" #>

<#
var targetNamespace = "GreaterHeights.Test.Domain";

    IServiceProvider serviceProvider = (IServiceProvider)this.Host;
    DTE dte = serviceProvider.GetService(typeof(DTE)) as DTE;  
    var project = dte.ActiveDocument.ProjectItem.ContainingProject;
#>
module greaterheights.constants{

<#


 foreach (CodeClass c in FindClasses(project, targetNamespace, "")) { #>
    export class <#= c.Name #>Constants {

       public static <#= c.Name #>Entity : string = '<#= c.Name #>'; 
<#     var properties = c.Members.OfType<EnvDTE.CodeProperty>()
           .Where(p => p.Access.HasFlag(vsCMAccess.vsCMAccessPublic))
           .OrderBy(p => p.Name);
       foreach (var prop in properties) { 
#>
       public static <#= prop.Name #> : string = '<#= prop.Name #>'; 
<#     } #>

   }

<# } #>

}

<#+ List<CodeClass> FindClasses(Project project, string ns, string className) {
        List<CodeClass> result = new List<CodeClass>();
        FindClasses(project.CodeModel.CodeElements, className, ns, result, false);
        return result;
    }

    void FindClasses(CodeElements elements, string className, string searchNamespace, List<CodeClass> result, bool isNamespaceOk) {
        if (elements == null) return;
        foreach (CodeElement element in elements) {
            if (element is CodeNamespace) {
                CodeNamespace ns = element as CodeNamespace;
                if (ns != null) {
                    if (ns.FullName == searchNamespace)
                        FindClasses(ns.Members, className, searchNamespace, result, true);
                    else
                        FindClasses(ns.Members, className, searchNamespace, result, false);
                }
            } else if (element is CodeClass && isNamespaceOk) {
                CodeClass c = element as CodeClass;
                if (c != null) {
                    if (c.FullName.Contains(className))
                        result.Add(c);

                    FindClasses(c.Members, className, searchNamespace, result, true);
                }
            }
        }
    }

    #>
Simply add this template to the scripts directory of your web project, replace the targetNamespace with the namespace of your EntityFramework project and select the “Run Custom Tool” context menu for the template. The generated typescript file should look something similar to this.
module greaterheights.constants{

    export class Employee {

       public static EmployeeEntity : string = 'Employees'; 
       public static EmailAddress : string = 'EmailAddress'; 
       public static Forename : string = 'Forename'; 
       public static Id : string = 'Id'; 
       public static Surname : string = 'Surname'; 

   }
}
Now simply reference the file in your Typescript breeze data service and you can create the same query without magic strings.
var manager = new breeze.EntityManager('api/northwind');

var query = new breeze.EntityQuery()
    .from(greaterheights.constants.EmployeeEntity);
manager.executeQuery(query).then(function(data){
    ko.applyBindings(data);
}).fail(function(e) {
    alert(e);  
});