2016-01-29

AngularJs - binding HTML

The directive ng-bind will escape HTML to avoid data acting maliciously. If you want to output html you need to use ng-bind-html

<div ng-bind-html="someHtmlBody"/>

The important step to getting this working is to ensure the script angular-sanitize.js is referenced on your page, and it is specified as a dependency when creating a module....

var app = angular.module("MyApp", ["ngSanitize", "OtherDependencies"]);

AngularJS routes with ASP MVC Forms authentication

The ASP MVC app I am working on uses forms authentication with a timeout. This means that when the session has timed out and the user clicks refresh they get redirected to a login page, and after that they get directed back to the original page without the deep-linked client-side # part of the url. 

The solution to this is as follows:

The first thing to do is to have the ASP MVC server side capture any URLs that should related to your client-side angular routing and return the single-page app HTML. When registering your ASP MVC routes add the following rule
        routes.MapRoute(
            name: "Angular",
            url: "x/{*clientPath}",
Where the "x/" is the base part of your client app, of course you can do without the "x" in the URL if your entire app is a single-page angular app, in which case you will need to add a preceding rule to render your ASP MVC server side account-login page.
Then in your Angular app make sure you use Html5 mode, like so
app.config(["$locationProvider", "$routeProvider", function ($locationProvider, $routeProvider) {

    $locationProvider.html5Mode({
        enabled: true,
        requireBase: false,
        rewriteLinks: true
    });

    $routeProvider.when("/x/docs/upload", {
        ......
    });
    $routeProvider.when("/x/docs/view", {
        ......
    });
    $routeProvider.otherwise({
        redirectTo: "/x/docs/upload"
    });
}]);
When you open your browser and navigate to http://mysite/x/what/ever/you/like the server side will use XController.Index to render Views\x\Index.cshtml, which will load your single page app, and then ngRoute will take over and present the relevant view for the "x/what/ever/you/like" part.

2015-01-07

Node.js Express, form validation, and keeping previously posted form values

I've been playing with Node.js and the Express webserver framework as a learning experience, it's good fun :)

In the C# ASP MVC world using the Razor view engine I can define my user interface elements like this...

@Html.TextBoxFor(x => x.EmailAddress)
@Html.ValidationMessageFor(x => x.EmailAddress)

This will do three things

  1. It will create the html output for an input element
  2. If the view is being rendered as a result of a POST it will set the value of the input to the value posted.  This is useful for when you have a form validation error and don't want to have to force the user to re-enter all of their input.
  3. If there is an error message registered for EmailAddress it will display the error text
*Note that error messages are registered using ModelState.AddModelError("EmailAddress", "The error message")

Node.js, Express, and Jade

Express is a very light weight framework so doesn't do any of this stuff for you, so I had to hunt around for a solution which I am now blogging for the sake of record.

To satisfy my validation requirement I used express-validator by Christoph Tavan (install it using "npm install express-validator").  It is used like this

app.js
var expressValidator = require('express-validator');
app.use(expressValidator());

mycontroller.js
app.get('/signup', signUp);
app.post('/attemptSignUp', attemptSignUp);

function signUp(req, res) {
    res.render('signup', {
        title: 'Sign up',
        errors: []
    });
}

function attemptSignUp(req, res) {
    req.checkBody('username', 'Required').notEmpty();
    res.locals.errors = req.validationErrors(true);
    res.render('signup', {
        title: 'Sign up',
        errors: req.validationErrors(true)
    });
}

As you can see in the above source I have created two routes. The first will GET the view at /signup, the second will accept a POST from the form generated in the /signup request.  Because we have added the express-validation middleware in the main app we now have access to a new checkBody method on the request object.  Any checks that fail will be reported by the req.validationErrors method.

The result of validationErrors is fed into the Jade view engine with the name "errors", in the /signup action this is an empty array because there are no errors, and in the /attemptSignUp the errors from the validation are passed in.

To display the errors requires a simple addition to your Jade view

signup.jade
if (errors['username'])
    span.text-error #{errors['username'].msg}

If there is an error for "username" then a span with the css-class "text-error" and with the error message as its contents.

Keeping form input

Having to re-enter form data whenever you get something wrong is annoying.  I haven't yet found Express middleware that deals with this so I made my own very simple library.

To use it requires the following addition to your jade view

signup.jade
input(type="text", name="username", value="#{posted('username')}", required)

I have added the "required" keyword for client-side validation, so in this example the username must be invalidated on the server, perhaps because the user name is already in use, but you can remove it for the sake of testing.

For checkboxes you can use this
input(type="checkbox", name="accepttermsandconditions", checked=posted.checked('accepttermsandconditions'))

The new lib is located in ./lib/form-values/index.js

exports = module.exports = function (req, res, next) {
    var body = req.body;
    if (typeof body === 'undefined') {
        return next(new Error('form-values must be used after body-parser'));
    }
    var bodyKeys = Object.keys(req.body);
    res.locals.posted = function (name, defaultValue) {
        if (bodyKeys.indexOf(name) === -1) {
            if (typeof defaultValue === 'undefined')
                return '';
            return defaultValue;
        } else {
            return req.body[name];
        }
    }
    res.locals.posted.checked = function (name) {
        var postedValue = res.locals.posted(name, null);
        if (postedValue === null)
            return undefined;
        return '';
    }
    return next();
};

If you look closely you will see it is also possible to call posted('fieldname') with a second parameter which will act as a default value only if there is no posted value.

2014-10-04

AngularJS - Triggering code whenever ng-view updates


//Create the module
var app = angular.module('someapp', ['ngRoute']);

//Config the routes
app.config(configRoutes);

function configRoutes($routeProvider) {
    $routeProvider
        .when('/', {
            templateUrl: '/angular/viewtemplates/admin/index.html',
            controller: 'AdminController'
        })
        .when('/categories', {
            templateUrl: 'angular/viewtemplates/admin/categories/index.html',
            controller: 'CategoryIndexController'
        })
}

//Make sure we are notified whenever the ng-view is updated
app.run(function($rootScope) {
    $rootScope.$on('$viewContentLoaded', function() {
       $('table[data-toggle="table"]').bootstrapTable();
    });
});

2013-11-09

Windows welcome screen slow

After I log in to Windows 7 the welcome screen stays on for ages, in the past it was almost instant.  I’ve tried various suggestions from forums and none of them worked, then it struck me what it was!

Windows was trying to reconnect network drives after I had logged in, but one of them (a connection to my iMac) was unobtainable because my iMac was off.  I disconnected the mapped network drives and speed is back to normal Smile

2013-11-04

Installing Ruby on Rails, RubyMine and MongoDB on Ubuntu Linux

Here are some really basic instructions which should work on a virgin installation of Ubuntu Linux.  I tried following some instructions in a book but they were awful, these are what I ended up with.

Install some installation helper tools etc

sudo apt-get install build-essential git-core
sudo apt-get install curl
bash -s stable < <(curl -s https://raw.github.com/wayneeseguin/rvm/master/binscripts/rvm-installer)
echo '[[ -s "/home/x/.rvm/scripts/rvm" ]] && source "/home/x/.rvm/scripts/rvm"' >> ~/.bashrc
source ~/.bashrc

Install JavaScript interpreter

sudo apt-get install nodejs

Install MongoDB server and clients

sudo apt-get install mongodb-server
sudo apt-get install mongodb-clients

Install Rails

sudo apt-get install rails

Install Ruby 1.9.3 and set it as the default version to use

rvm install 1.9.3
rvm use --default 1.9.3

Install Gems required by Ruby

gem install rails
gem install mongoid
gem install therubyracer

Java JDK for RubyMine

sudo apt-get install openjdk-7-jdk
export JAVA_HOME=/usr/lib/jvm/java-7-openjdk-amd64/bin

Now download RubyMine from http://www.jetbrains.com/ruby/download/ then extract it and move it to /opt

Start RubyMine, thereafter it will be available in the start menu

cd /opt/RubyMine-5.4.3.2.1/bin

Create a directory for Rails projects and cd into it

mkdir ~/RailsProjects
cd ~/RailsProjects

Create a new rails project without active record

rails new TestMongoDB --skip-active-record

Open the project using RubyMine and edit the GemFile contents, add the following

gem 'bson', '~> 2.0.0.rc2'
gem 'mongoid', git: 'git://github.com/mongoid/mongoid.git'

In RubyMine go to the Tools menu and select Bundler->Install to install the Ruby Gems we have just added to the project.

Create a config file in config/mongoid.yml and paste in the following

development:
  sessions:
    default:
      database: testercles
      hosts:
        - localhost

Go back to your Terminal window to create some data to retrieve

mongo
use testercles
db.Books.save( { Title : "This is the title" })

Create a Book class in app/models/book.rb

require 'rails/mongoid'
class Book
  include Mongoid::Document

  field :Title, type: String
end

In RubyMine go to the Tools menu then “Run rails generator”->Controller (or press ctrl+alt+G then type controller) – name the controller Home

Add the following require to the top of the class file and insert the following index method

require 'mongoid'

  def index
    @book = Book.all.first()
  end

Create a view for this controller/action, you can do this by clicking the icon in the gutterbar to the left of the method name, this will create the view automatically for you.  Set the view html to the following

The book title is: <%= @book.Title %>

Edit config/routes.rb and add the following root

root :to => "home#index"

Now run your app and navigate your browser to http://localhost:3000

2012-12-21

Decorating Unity extension

First I want to give credit where it is due, the code in this post is based largely on the code I found in this post by Jim Chrisopher.
The original code required me to register my decorators before registering the type I wanted to decorate.  I didn't like this because I prefer to register all the low-level services from within their own assemblies and then have the app (website etc) decorate those types at a higher level.  So I changed the code in the following ways
  1. It now uses the UnityContainer.Configure<> method to decorate types.
  2. The decorators may be registered before or after the registered type, or both, it doesn't matter.
  3. It is possible to register both generic and non-generic types, and both will be used if applicable (e.g. ICommand<> and ICommand<string> would apply to Command<string> but only ICommand<> would apply to Command<int>.)
  4. It works with child containers.
  5. It uses the context.NewBuild method instead of requiring an IUnityContainer reference.
The code is used like this
//Program.cs
using System;
using Microsoft.Practices.Unity;

namespace ConsoleApplication5
{
    class Program
    {
        static void Main(string[] args)
        {
            var container = new UnityContainer();
            container.AddNewExtension<Decorating>();
            container
                .Configure<Decorating>()
                    .Decorate(typeToDecorate: typeof(ICommand<>), decorateWith: typeof(CommandLogger<>))
                .Configure<Decorating>()
                    .Decorate<ICommand<string>, CommandLogger<string>>();

            container.RegisterType(typeof(ICommand<>), typeof(Command<>));

            var intCommand = container.Resolve<ICommand<int>>();
            intCommand.Execute(42);

            var stringCommand = container.Resolve<ICommand<string>>();
            stringCommand.Execute("Hello world");

            Console.ReadLine();
        }
    }
}

//An iterface type to resolve at runtime
using System;

namespace ConsoleApplication5
{
    public interface ICommand<T>
    {
        void Execute(T value);
    }

    public class Command<T> : ICommand<T>
    {
        public Command() 
        {
        }

        public void Execute(T value)
        {
            Console.WriteLine("Command: " + value.ToString());
        }
    }

    public class CommandLogger<T> : ICommand<T>
    {
        readonly ICommand<T> Inner;

        public CommandLogger(ICommand<T> inner)
        {
            this.Inner = inner;
        }

        public void Execute(T value)
        {
            Console.WriteLine("CommandLogger: " + value.ToString());
            Inner.Execute(value);
        }
    }
}



And here it the code which implements the decorating extension. The trick is to allow the normal build up first then set that initial instance as the parameter for creating the first decorator, then that decorator as the parameter for the next decorator to build, and so on.


//DecoratingExtension.cs
using System;
using Microsoft.Practices.Unity;
using Microsoft.Practices.Unity.ObjectBuilder;

namespace ConsoleApplication5
{
    public class Decorating : UnityContainerExtension
    {
        DecoratorTypeRegister Register;

        public Decorating()
            : base() { }

        internal Decorating(IUnityContainer container, DecoratorTypeRegister register)
        {
            container.AddExtension(this);
            this.Register.CopyFrom(register);
        }

        protected override void Initialize()
        {
            this.Register = new DecoratorTypeRegister();
            this.Context.ChildContainerCreated += Context_ChildContainerCreated;
            Context.Strategies.Add(
                    new DecoratingBuildStrategy(Register),
                    UnityBuildStage.PreCreation
            );
        }

        void Context_ChildContainerCreated(object sender, ChildContainerCreatedEventArgs e)
        {
            var decoratingExtension = new Decorating(e.ChildContainer, Register);
        }

        public IUnityContainer Decorate(Type typeToDecorate, Type decorateWith)
        {
            Register.Register(typeToDecorate: typeToDecorate, decorateWith: decorateWith);
            return Container;
        }

        public IUnityContainer Decorate<TTypeToDecorate, TDecorateWith>()
        {
            Decorate(typeof(TTypeToDecorate), typeof(TDecorateWith));
            return Container;
        }
    }
}


//DecoratingBuildStrategy.cs
using System;
using System.Collections.Generic;
using Microsoft.Practices.ObjectBuilder2;
using Microsoft.Practices.Unity;

namespace ConsoleApplication5
{
    internal class DecoratingBuildStrategy : BuilderStrategy
    {
        readonly DecoratorTypeRegister Register;

        internal DecoratingBuildStrategy(DecoratorTypeRegister register)
        {
            this.Register = register;
        }

        public override void PostBuildUp(IBuilderContext context)
        {
            base.PostBuildUp(context);
            Type typeRequested = context.OriginalBuildKey.Type;
            if (!typeRequested.IsInterface)
                return;

            Type typeToBuild = context.BuildKey.Type;

            if (!Register.HasDecorators(typeRequested))
                return;

            var typeStack = new Stack<Type>(Register.GetDecoratorTypes(typeRequested));

            typeStack.ForEach(decoratorType =>
            {
                DependencyOverride dependencyOverride = new DependencyOverride(
                        typeToConstruct: typeRequested,
                        dependencyValue: context.Existing
                    );

                Type actualTypeToBuild = decoratorType;
                if (actualTypeToBuild.IsGenericTypeDefinition)
                {
                    Type[] genericArgumentTypes = context.OriginalBuildKey.Type.GetGenericArguments();
                    actualTypeToBuild = actualTypeToBuild.MakeGenericType(genericArgumentTypes);
                }

                context.AddResolverOverrides(dependencyOverride);
                context.Existing = context.NewBuildUp(new NamedTypeBuildKey(actualTypeToBuild));
            });
        }
    }
}

//DecoratingTypeRegister
using System;
using System.Collections.Generic;

namespace ConsoleApplication5
{
    internal class DecoratorTypeRegister
    {
        readonly Dictionary<Type, List<Type>> DecoratedTypes;

        public DecoratorTypeRegister()
        {
            this.DecoratedTypes = new Dictionary<Type, List<Type>>();
        }

        public void Register(
            Type typeToDecorate,
            Type decorateWith)
        {
            if (typeToDecorate == null)
                throw new ArgumentNullException("TypeToDecorate");
            if (!typeToDecorate.IsInterface)
                throw new ArgumentException("TypeToDecorate must be an interface");
            if (decorateWith == null)
                throw new ArgumentNullException("DecorateWith");

            List<Type> registeredDecoratorTypes;
            if (!DecoratedTypes.TryGetValue(typeToDecorate, out registeredDecoratorTypes))
            {
                registeredDecoratorTypes = new List<Type>();
                DecoratedTypes.Add(typeToDecorate, registeredDecoratorTypes);
            }
            registeredDecoratorTypes.Add(decorateWith);
        }

        public void Register<TTypeToDecorate, TDecorateWith>(
            TTypeToDecorate typeToDecorate,
            TDecorateWith decorateWith)
        {
            Register(typeToDecorate: typeof(TTypeToDecorate), decorateWith: typeof(TDecorateWith));
        }

        public IEnumerable<Type> GetDecoratorTypes(Type typeToDecorate)
        {
            if (typeToDecorate == null)
                throw new ArgumentNullException("TypeToDecorate");
            if (!typeToDecorate.IsInterface)
                throw new ArgumentException("TypeToDecorate must be an interface");

            var result = new List<Type>();
            List<Type> registeredDecoratorTypes;
            if (DecoratedTypes.TryGetValue(typeToDecorate, out registeredDecoratorTypes))
                result.AddRange(registeredDecoratorTypes);
            if (typeToDecorate.IsGenericType)
                if (DecoratedTypes.TryGetValue(typeToDecorate.GetGenericTypeDefinition(), out registeredDecoratorTypes))
                    result.AddRange(registeredDecoratorTypes);
            return result;
        }

        public IEnumerable<Type> GetDecoratorTypes<TTypeToDecorate>()
        {
            return GetDecoratorTypes(typeof(TTypeToDecorate));
        }

        public bool HasDecorators(Type decoratorType)
        {
            return DecoratedTypes.ContainsKey(decoratorType) ||
                (decoratorType.IsGenericType && DecoratedTypes.ContainsKey(decoratorType.GetGenericTypeDefinition()));
        }

        internal void CopyFrom(DecoratorTypeRegister register)
        {
            foreach (var item in register.DecoratedTypes)
            {
                List<Type> decoratorTypeList;
                if (!DecoratedTypes.TryGetValue(item.Key, out decoratorTypeList))
                {
                    decoratorTypeList = new List<Type>();
                    DecoratedTypes.Add(item.Key, decoratorTypeList);
                }
                decoratorTypeList.AddRange(item.Value);
            }
        }
    }
}