Tuesday, December 27, 2016

TypeScripting AngularJS 1.x - Directives

This post is part of TypeScripting AngularJS 1.x series.Other posts are listed below.

  1. TypeScripting AngularJS 1.x - Define module
  2. TypeScripting AngularJS 1.x - Define module - improvements for big enterprise apps Improvement
  3. TypeScripting AngularJS 1.x - Using $http 
  4. TypeScripting AngularJS 1.x - Directives

Angular Directives using TypeScript

Below is a mechanism to create typed Angular directives using TypeScript.

The main thing is that our directive class needs to implement ng.IDirective. After that we can have the corresponding ng.IDirective members. The advantage here is that we don't need to memorize or google for what are the members required for directive. Its all there in ng.IDirective

export class ProjectsDirective implements ng.IDirective {
    public restrict: string;
    public templateUrl: string;
    public controller: any;
    public controllerAs: string;
    public bindToController: boolean | { [boundProperty: string]: string };
    public scope: boolean | { [boundProperty: string]: string };
    constructor() {
        this.restrict = 'E';
        this.templateUrl = 'JS/app/projects.component.html';
        this.controller = "ProjectsController";
        this.controllerAs = "ctrl";
        this.bindToController = true;
    }
}

Above code snippet is taken directly from my personal web site. The members such as bindToController, controller etc... are optional. This is not enough to get the ProjectsDirective available in our application. For that we have to register it with Angular application.

Code snippet below shows the registration.

AppModule.getInstance().registerDirective("projects", () => {
    return new ProjectsDirective() 
});

It gets the instance of the Angular module and calls the registerDirective function. The object here is  a wrapper over real Angular module object. That function in turn calls the real Angular.directive function.

Dependency injection

The dependencies to the directive can be accepted by the directive factory / creation function. That function then can pass those injected objects to the directive constructor. 

Sample code

The code is from my personal web site and it is in GitHub.
Simply clone the repo and compile using Visual Studio 2015. It uses TypeScript 1.8.

Tuesday, December 20, 2016

Why I choose Angular 1.x for www.JoymonOnline.in while Angular2 is out

What is the present tech landscape?

If we look at present web development technologies, we can see everything is revolving around client side HTML generation. The interesting thing at client side web development is that, there are new tools and frameworks getting released every week. It is very difficult to select one and get something out using that. By the time we complete analysis on one tool or framework, the next one will be out by saying its better than the existing. If we keep analyzing, we never will be able to do something useful.

Recently, I decided to convert my personal web site to pure client side solely to avoid hosting cost. It currently is .aspx based server side html generation model. The server side code help me to connect easily with third parties such as Github, Blogger etc...I don't need to worry about whether the viewers network blocks GitHub or Blogger APIs. If I am converting to client side I had to write some JavaScript to do that third party integrations. Hence I have to analyze the client side technology stack. Important thing for me is to convert the app to pure client side app before March 2017 else I have to renew the hosting space again. So its is highly time bound

In short, I selected Angular JS 1.x over other technologies even by avoiding Angular 2. This post talks about my journey towards Angular JS 1.x to do this time bound task over Angular 2.

There is no standard tooling for ng2

We can easily compare the scenario with the US restaurants v/s Indian restaurants.
In India, if we got o middle or lower level restaurants and order Masala Dosa, they will give us a standard Masala Dosa. The standard changes from state to state and district to district. Very less options to customize. But if we are in American restaurant, they will ask so many questions, if we order a sandwich. What type of cheese, what ingredients, type of bread etc...

In Angular 1, things were pretty much like restaurants in India. There are standard tools. Only some confusion comes in the language. Whether to go with JavaScript, TypeScript or CoffeeScript.

But in Angular 2, there are many tools and we have to pick up the combination what works for us. What framework for module loading, how and when to compile TypeScript to JS, how to do packaging.  New tools are popping up frequently too. Though there is official recommended tool chain, I don't think it is working out for many developers. May be they are not productive or are complex which needs more technical knowledge. Else people will never spend time to invent more and more tools.

Though the ng2 framework is kind of mature the tools are not.

This may be controversial statement. There will be many disagreements as some tools works for some and all can find some combinations.

Many tools are in beta

The main tool came along with ng2 is the command line tool called  Angular cli. At the time of writing this post, it is still in beta. They recently switched from SystemJS to WebPack. 

Some tools doesn't mean for Windows

Suppose we take the risk of using a beta tool for doing development, there are still issues. Some are more tailored to OS other than Windows. Though we can mitigate the issues, it eats our time.

Compiling TypeScript in browser is for demos till browsers understand TypeScript

Now a days most of us agree that the compilation of TypeScript needs to be done along with build process. Though there are options available to compile TypeScript in browser, it will reduce the start time of our application. The other group is telling that, some browsers are expected to support TypeScript directly in future so the compilation can be done by detecting the browser.

This is same, if we select ES6 as well. Some says we should compile down to ES5 always the other side argues that it should be done at Browser by detecting the feature support.

Its all good if we are developing a demo to get a project or samples. But for something to be done in a time based manner, we cannot be trapped in these arguments.

Why not code Angular2 in ECMA 5 JS?

Come on...Though there are many good tutorials available which explains writing Angular 2 application using ES 5, I never want to do. There are many reasons. One big reason is going forward, if we struck in an issue the sample snippets or solutions provided will never be in ES5. We have to find out how to convert the ES6 or TS code into ES5.

But we should definitely try writing the Angular 2 code in ES5 for understanding purpose. Else if something goes wrong in our compiled ES5 code, we may not be able to find out.

Why not build a brand new site and switch one morning

This is a famous question we all might have faced during any migration effort. The developers who never tried rewriting a software under proper timelines, will always advocate this strategy. But others never agree on complete rewrite. When we look at any software which is running for long, we can see so many pain points of previous developers and hacks, anti patterns etc...If we just start rewriting,  we will also have to go to the same pain points. So why should we take unwanted risk? Lets always divide and conquer part by part.

In my personal web site scenario, I was the only developer and I am the one who is going to rewrite also. But I had taken so many things from here and there during initial development and unfortunately, I didn't document anywhere even in this blog. Since I use my brain mainly for generating ideas, I don't remember all the pain points now. Hence there is no need to take risk.

Again why should we take same old risks as there will be new risks during the conversion to client side.  By this time I already got an issue related to Angular date formatting in Windows Phone 7. Please don't ask apart from me who else using Window Phone.

The continuous delivery system

I currently use free service from AppVeyor to run continuous delivery of my web site. Since its a Visual Studio solution, AppVeyor detect it, compile the same, run tests, package and deploy to the server. To my best understanding ng2 heavily depends on NPN though there is a nuget package for ng2. AppVeyor can be configured to use NPN, but it is again time consuming.

When is the best time for ng2

None of the tools and technologies are going to be there for ever. The technologies are suitable to the current landscape. There are new cool technologies coming out. Below are some

  • ReactJS (This is already out. Though it is not a full fledged framework like Angular, it is a choice)
  • WebComponents
  • WebAssembly (we may be developing browser apps using C#. Remember the old Silverlight days)
The driving factor in this conversion is the cost to host ASP.Net site. After that based on the situation, there may be pressing situation to convert to any one of the above technologies. But right now, it is impossible to predict.

These are my own views about selection of AngularJS 1.x for a personal/portfolio site. These are not  applicable to all the scenarios. 

Tuesday, December 13, 2016

Handle once for many events via sliding timer.

As a developer we might have encountered many situations where we have to do certain things when something triggers but it triggers so frequently which makes our handler code run many times and it affecting performance. The functionality might be achieved by responding to last trigger. In .Net way, we can take events as triggers and if we want to handle event which is firing frequently it affects the performance.

Coming to an example for more clarity. Suppose we need to do something when the network is connected or disconnected, we can hook into the NetworkAvailabilityChanged or NetworkAddressChanged and write the code. But the network sometimes can get fluctuations, and these events may fires frequently but we don't need to respond for each event but to the last event. This is same if we want to show the MousePosition. We should only handle the last mouse move event. Not all. 

The event is firing rapidly. Need to handle the last one.

The major problem here is to identify which is the last one. In other words how much time we need to wait without any event firing to determine the last one.

This is purely the decision of the developer based on the situation. In some situations we can easily conclude that, if there is a 1 second delay the previous one was the last event. Sometimes that delay may be 5-10 seconds or can be small in milliseconds.

In short, many event firings happened but no need to handle once for all by determining a last point. This can be done using sliding timer mechanism or simple timer monitor.

Sliding timer

There is no  timer class in .Net framework called SlidingTimer. This is just a mechanism to reset the time based on triggers. If no event triggered, for a specified time, the timer ticks and the operation can be done.

When this should not be used

 If every event needs to be handled we cannot use this sliding timer mechanism. For example a sensor event or data feed where each and every event brings different data and needs to be processed.

Sample code

Below is a sample WPF implementation. This sample is trying to show the location of a window in a textblock whenever the window is moved. Since the LocationChanged event fires rapidly it uses SlidingTimer to determine when the user stops dragging the window. In other words, if the LocationChanged firing started and stops firing for 2 seconds, it the best time to update the location in textbox. First lets take a look at the consuming side.
private readonly int IdleTimeInMilliSecondsRequiredToProcessEvent = 2000;
SlidingTimer slidingTimer;
private void InitializeAndStartSlidingTimer()
{
    if (slidingTimer == null)
    {
        slidingTimer = new SlidingTimer(IdleTimeInMilliSecondsRequiredToProcessEvent);
        App.Current.MainWindow.LocationChanged += MainWindow_LocationChanged;
        slidingTimer.Tick += (sender, args) =>
        {
            this.Dispatcher.BeginInvoke(new Action(() =>
            {

                string loc = $"{App.Current.MainWindow.Left},{App.Current.MainWindow.Top}";
                this.LocationTextBlock.Text = loc;
                Console.WriteLine(loc);
            }));
        };
    }
}
private void MainWindow_LocationChanged(object sender, EventArgs e)
{
    Console.WriteLine("Event fired restart sliding timer");
    slidingTimer.StartOrRestart();
}
The above code can be in any WPF UI component's code behind file. Prerequisite is to have a TextBlock called LocationTextBlock in the UI class. InitializeAndStartSlidingTimer() can be called in the beginning or at any suitable time to initialize the SlidingTimer. Since the Window.LocationChanged is subscribed after initialization, its fine here. Those can vary depends on our scenario. 

Here the SlidingTimer is initialized with an idle timeout which required to tick after it is started or restarted. In the MainWindow_LocationChanged event handler, the slidingTimer is restarted. If there is no StartOrRestart() called continuously for 2000 milliseconds, the Tick event will fire. The Tick event handler uses dispatcher to manipulate the UI as the event fires in different thread.

Now lets see how the SlidingTimer class looks like
internal sealed class SlidingTimer
{
    Timer _internalTimer;

    private void OnTick(EventArgs args)
    {
        if(Tick !=null)
        {
            Tick(this, args);
        }
    }
    /// <summary>
    /// Fires in separate thread, when the there is enough delay to execute task.
    /// </summary>
    public event EventHandler Tick;
    int _intervalInMilliSeconds;
    public SlidingTimer(int intervalInMilliSeconds)
    {
        _intervalInMilliSeconds = intervalInMilliSeconds;
        _internalTimer = new Timer((state) =>
        {
            OnTick(EventArgs.Empty);
        });
    }
    internal void StartOrRestart()
    {
        _internalTimer.Change(_intervalInMilliSeconds, Timeout.Infinite);
    }
}
Here a thread timer is used for timing purpose. After it is started, the invocation of the callback event handler is controlled by the StartOrRestart(). Suppose the interval is 2 seconds, if internal timer starts and the StartorRestart() called after 1 seconds the total time slides to 3 seconds to get the event fired. This is simple sliding mechanism.

Monitoring timer 

The original use case can be done by using a normal timer as well. The event handler can just set a flag to indicate the processing is required. When the timer ticks it can check the flag and do the operation. After timer operation it needs to reset the flag.

Happy coding.