Angular.js: creating services

And a quick post on how to create a service.

Angular service should contain code shared across controllers; code that doesn’t need to touch $scope directly – this is a controller’s job.

 To begin, declare a module, containing services:

angular.module('hubServices', [])
    .factory('adminHub', function () {
        function hubServc(){
            this.getUsers = function(){
               return [
                    {"name":"Bob"},
                    {"name":"Bill"}
                ];
            }
        };

        return new hubServc();
    });

This will declare a module named ‘hubServices’, with service named ‘adminHub’. Factory method can return anything (an object or a function (yeah, i know function is an object)), in this case I return an object with a single function.

In html, add this markup:

<ul ng-controller="OneController">
    <li ng-repeat="user in users">{{user.name}}</li>
</ul>
<script type="text/javascript">
    angular.element(document).ready(function () {
        angular.bootstrap(document, ['hubServices']);
    });


    function OneController($scope, adminHub) {
        $scope.users = adminHub.getUsers();
    }
</script>

 This will create a UL which uses the OneController function as a controller.

OneController function gets an instance of adminHub via angular’s dependency injection – note how the 2nd parameter name is same as the name provided to factory function, and how bootstrap contains name of a module.

 And that’s pretty much it.

See the results here: http://jsfiddle.net/etcoding/vAzb7/5/

Angular.js: creating filters

Playing with Angular.js here. The learning curve is pretty steep in the beginning, but the result is worth it, imo.

Filters allow to apply various data transformations on the view, making it easy to either actually filter the data, or turn it into something else.

To create a filter, you need to add a .filter method to a module. 

Module in angular is something like a utility class, containing one or more of the following: services, directives, filters, or other modules.

 So, to start, create a new js file, name it filters.js (just for this example), with this code:

 

angular.module('filters', [])
    .filter('minLen', function () {
        return function (input, minLen, message) {
            minLen = minLen || 0;
            message = message || 'Too short';

            if (typeof (input) === 'undefined' || input.length < minLen)
                return message;
            return input;
        }
    });

    

This creates a new module, named ‘filters’ (this is what angular uses to find and inject it later on), and adds a filter ‘minLen’ to the module.

Filter should return a function, doing some input processing. This filter will also take min length and error message parameters, which are optional.

Then add this html inside a <body> tag:

<input type="input" ng-model="filteredInput">
<span>{{filteredInput | minLen:3:'make it longer'}}</span>

<script src="Scripts/angular.min.js" type="text/javascript"></script>
<script src="Scripts/Modules/filters.js" type="text/javascript"></script>

<script type="text/javascript">
    angular.element(document).ready(function () {
        angular.bootstrap(document, ['filters']);
    });
</script>

 

 This creates an input field, and binds it to the ‘filteredInput’ field inside a $scope (angular variable, which contains the data to be consumed by views).

Span field will be bound to the same field, and we’ll apply the filter to the output.

The code in the end calls a boot strap, initialization code that tells angular to run, treating ‘document’ as a boundary, and load the ‘filters’ module.

See the working version here: http://jsfiddle.net/etcoding/wURVY/5/

SignalR: How to get a current Hub instance

Once in a while, it’s helpful to call a Hub method from a controller, responding to some server side event.  Took me a while to figure this out, but in the end, this is easy.

DefaultHubManager hubManager = new DefaultHubManager(GlobalHost.DependencyResolver);
var hub = hubManager.ResolveHub("AdminHub"as AdminHub;
 
hub.SendMessage("woohoo");

One thing I don’t like is having to pass a hub name as a string – I think they should’ve asked for type. Easy enough to fix with a helper or extension method.

Code sample: Lucene.Net

A small code sample on Lucene.NET usage:

// Where the indexes will be stored.

Lucene.Net.Store.MMapDirectory dir = new Lucene.Net.Store.MMapDirectory(new DirectoryInfo(@"d:	emplucenemm"));


var version = Lucene.Net.Util.Version.LUCENE_29;
var analyzer = new Lucene.Net.Analysis.Standard.StandardAnalyzer(version);

// Create indexes
using (Lucene.Net.Index.IndexWriter idxWriter = new Lucene.Net.Index.IndexWriter(dir, analyzer, Lucene.Net.Index.IndexWriter.MaxFieldLength.UNLIMITED))
{

	Lucene.Net.Documents.Document doc1 = new Lucene.Net.Documents.Document();

	var fldTitle = new Field("Title", "Analyzer Class: Parsing the Documents", Field.Store.YES, Lucene.Net.Documents.Field.Index.ANALYZED);  // store index and original value
	fldTitle.SetBoost(1.5f);  // This will set the boost to this field
	doc1.Add(fldTitle);
	doc1.Add(new Field("Url", "http://www.blah.com/1", Field.Store.YES, Lucene.Net.Documents.Field.Index.NOT_ANALYZED));  // this field is not searched, and will be used as metadata
	doc1.Add(new Field("Body", "Most likely, the data that you want Lucene is plain text English", Field.Store.NO, Lucene.Net.Documents.Field.Index.ANALYZED));  // Don't need to store the original text, this is a search-only field

	idxWriter.AddDocument(doc1);

	Lucene.Net.Documents.Document doc2 = new Lucene.Net.Documents.Document();

	fldTitle = new Field("Title", "Adding a Document/object to Index with title2", Field.Store.YES, Lucene.Net.Documents.Field.Index.ANALYZED);
	fldTitle.SetBoost(1.5f);
	doc2.Add(fldTitle);
	doc2.Add(new Field("Url", "http://www.blah.com/2", Field.Store.YES, Lucene.Net.Documents.Field.Index.NOT_ANALYZED));
	doc2.Add(new Field("Body", "Now you need to index your documents or business objects. To index an object, you use the Lucene Document class", Field.Store.NO, Lucene.Net.Documents.Field.Index.ANALYZED));

	idxWriter.AddDocument(doc2);
	idxWriter.Commit();
}

// search

Lucene.Net.Search.Query query = new MultiFieldQueryParser(version, new string[] { "Title", "Body" }, analyzer).Parse("data title2");  // looking for words "data", "title2" in all fields

using (Lucene.Net.Search.IndexSearcher idxSearcher = new Lucene.Net.Search.IndexSearcher(dir, true))

{
	TopScoreDocCollector collector = TopScoreDocCollector.create(100, true);
	idxSearcher.Search(query, collector);
	var sdocs = collector.TopDocs().ScoreDocs;

	for (int i = 0; i < sdocs.Length; i++)
	{
    	var docId = sdocs[i].doc;
	Document doc = idxSearcher.Doc(docId);
	string url = doc.GetField("Url").StringValue();
	}
}

Console.WriteLine("done");

TDD and work distribution

One of the uses of TDD that we’ve thought of is a work distribution. Say, you have a team of senior dev and a few junior/intermediate ones. So, instead of giving them specs on paper or whatever, senior dev can always write a test, and give it to the team members – “make this pass!”. This way a) you get all benefits of TDD b) you can always see the progress c) you have the most knowledgeable team member designing the system. I haven’t seen this before, which makes me wonder if there’s something wrong with this.. or no-one actually thought of this before ?