Thursday, February 28, 2013

IE7 don't have feelings, but it's a browser too


Having said that, it still needed be supported by JavaScript frameworks too despite IE10’s release


Yesterday I shared that AngularJS is not compatible with IE7 to colleague engineers during my AngularJS presentation, I should have been more creative on answering that given that I said JavaScript can even emulate x86 instruction set. JavaScript is a better VM than Java on this regard, I digress 



AngularJS is not incompatible to IE7 per se, it can’t work on IE7 out-of-the-box as string data type is the only type supported by IE7's JSON library. Enter JSON polyfill, it will plug the gaping hole of IE7's lack of native JSON library


Just use json3.min.js polyfill to make IE7 work with AngularJS:


<script src="angular.min.js"></script>
<!--<script src="json3.min.js"></script>-->

    
<body class="ng-app:myApp" id="ng-app">

       <div ng-app='myApp'>
              <div ng-controller="MyCtrl">
              1. Hello, {{title}}!           <input  ng-model="title" type="text" /><br/>
              2. Hello, {{hero.name}}!        <input  ng-model="hero.name" type="text" /><br/>
              3. Hello, {{hero.rescued}}!     <input  ng-model="hero.rescued" type="text" /><br/>
              4. Hello, {{hero.birthday}}!    <input  ng-model="hero.birthday" type="text" /><br/>   
              </div>
       </div>

</body>


<script>
    angular.module('myApp', []).controller(MyCtrl);

    function MyCtrl($scope) {
        $scope.title = 'Man of Steel';
        $scope.hero = { name: 'Superman', rescued: 1337, birthday: new Date(2000, 1, 27, 0, 0, 0, 0) };
    }
</script>






It turns out one of our projects is using JSON polyfill, I surmise for IE7 compatibility too, albeit using version 2 only, json2.js


Open the above code on IE7, you'll see that number and date doesn't bind. Then include json3.min.js, number and date will bind 





Happy Coding! 

Tuesday, February 26, 2013

A primer on connection pooling

using System;
using System.Data;
using System.Data.SqlClient;
 
namespace Craft
{
    class Mate
    {
        // Connection pooling 101: http://msdn.microsoft.com/en-us/library/8xx3tyca.aspx
 
        // To check the number of connections made:
 
        static string checkPooledConnections =
@"SELECT spid, uid=rtrim(loginame), Program_name=rtrim(Program_name),
dbname=db_name(dbid), status=rtrim(status) 
FROM master.dbo.sysprocesses
WHERE program_name = '.Net SqlClient Data Provider'";
 
        static void Main(string[] args)
        {
            using (var connection = new SqlConnection("Integrated Security=SSPI;Initial Catalog=test"))
            {
                connection.Open();
                // Pool A is created.
 
                using (var cmd = connection.CreateCommand())
                {
                    string languageCode = "zh";
                    Console.WriteLine("Set Language: {0}", languageCode);
 
                    cmd.CommandType = System.Data.CommandType.StoredProcedure;
                    cmd.CommandText = "SetLanguage";
                    var prm = cmd.CreateParameter();
                    prm.ParameterName = "@LanguageCode";
                    prm.Value = languageCode;
                    cmd.Parameters.Add(prm);
                    cmd.ExecuteNonQuery();                   
                }
 
                ShowLanguage(connection);
                connection.Close();
            }
 
            using (var connection = new SqlConnection("Integrated Security=SSPI;Initial Catalog=Test"))
            {
                connection.Open();
                // Pool B is created because the connection strings differ.
 
                // Even the database is the same, the casing of the database name is different(uppercased T), hence connection pooler treating this connection as different connection                
 
                ShowLanguage(connection);
                connection.Close();
            }
 
            using (var connection = new SqlConnection("Integrated Security=SSPI;Initial Catalog=test"))
            {
                connection.Open();
                // The connection string matches pool A.
 
                Console.WriteLine("Shall show no language even this connection matches the connection pool A.");
                ShowLanguage(connection);
                connection.Close();
            }
 
            Console.WriteLine("\nPlease execute the following query on SSMS before hitting the Enter key. You shall see that there are only two connections made instead of three. Connection pooling is in effect\n\n{0}",
                checkPooledConnections);
            Console.ReadKey();
 
      
        }
 
        static void ShowLanguage(SqlConnection connection)
        {
            using (var getLang = connection.CreateCommand())
            {
                getLang.CommandType = CommandType.Text;
                getLang.CommandText = "select cast(CONTEXT_INFO() as varchar(5))";
               
                object userLanguageCode = getLang.ExecuteScalar();
                Console.WriteLine("Get Language: {0}\n", userLanguageCode);
                Console.ReadKey();
            }           
        }
       
    } // classmate
} // namespacecraft
 

SetLanguage SP:

create procedure SetLanguage(@LanguageCode varchar(5)) as
begin
    declare @binvar varbinary(128);
    set @binvar = cast(@LanguageCode as varbinary(128));
    set context_info @binvar;
end;

Sunday, February 10, 2013

RequireJS walkthrough

New technology names and acronyms I knew them...


...yet lacking real knowledge on them, I feel I'm a phony :(


I'm lucky I'm in an awesome company if not a perfect company, there are many engineers in the company who already have knowledge on new technologies which I don't know (yet) ツ And it's refreshing to know that we are not as homogenized when it comes to technology choices, some uses in-house ORMs, some of us uses NHibernate, some of us don't stop at ASP.NET MVC, some are seeking how to engineer things better, and are learning or already knew client-side MVC technology like AngularJS, KnockoutJS, Kendo MVVM(PSA: MVVM is a tweaked MVC), and other technologies like RequireJS, AMD, CORS


It's becoming a regular occurence when I'm having conversations with fellow engineers and they ask questions that are impressive, yet I don't know the answers for. Case in point, there's the questions about if RequireJS can be used with AngularJS, can AngularJS do CORS, what's the difference between AngularJS and KnockoutJS. And on CORS topic, I can only muster a JSONP answer(which I already tried and works on AngularJS), I'm exposed hahah! A quick trip to wikipedia while writing this post says that CORS is better than JSONP.


AngularJS supports CORS as far as the browser supported it too. Even the poster child javascript framework that abstracts away (read: jQuery) browser inconsistencies don't have CORS support for IE8 and IE9, as Microsoft didn't put CORS support on IE8 and IE9 and made a competing technology to CORS instead: http://bugs.jquery.com/ticket/8283


But alas! Microsoft can't be that stubborn for far too long, finally they embraced what everyone else are implementing, IE10 have CORS support


There's goes my Microsoft-rant-once-in-a-while fix for the month! :p


Back to regular programming.


Out these technologies, one thing that sticks out like a sore thumb to me is RequireJS. RequireJS facilitates dynamic loading of javascript files from client-side without using server-side technology(e.g. ASP.NET MVC, Java, PHP, etc). If we are embracing client-side MVC more and more and making server-side technologies a second fiddle to our application stack, this is where we need a technology like RequireJS.


It's time to rectify my lack of knowledge on that awesome Javascript technology, time to stop being a perpetual catch-up, in this article I'll show you how to use RequireJS.


To start with, we need to get RequireJS from NuGet.


Then try out the following sample code, remove Default.aspx and create Default.htm:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>RequireJS sample</title>
    <script src="/Scripts/jquery-1.4.1.min.js" type="text/javascript"></script>
    
    <script src="/Scripts/require.js"></script>
</head>
<body>

    Service: 
    
    <select id="ServiceType">
        <option value="/Services/FirstClass.js">First Class</option>
        <option value="/Services/SecondClass.js">Second Class</option>
    </select>    `
    
    <hr />
    <input type="button" id="Something" value="Test the Service"/>


    
    <script>



        $(function () {
            var service = null;

            $('#ServiceType').change(function () {
                var path = $(this).val();
                require([path], function (c) {
                    service = new c();                    
                });
            }).trigger('change');


            $('#Something').click(function () {
                if (service != null)
                    service.saySomething();
                else
                    alert('Service not yet loaded');
            });
        });
    </script>

        

</body>
</html>



To load your javascript files you'll use require function, the first parameter is an array of javascript files to load, the second parameter(can have third, fourth parameter and so on, if you need to load multiple javascript modules) is where your function/class definition goes to. In the above code, we are treating the passed function as a class, hence the new c()




Enclose your javascript files in define function.

/Services/FirstClass.js:
'use strict';

define([], function () {

    function FirstClass() {
        this.saySomething = function () {
            alert('Welcome aboard!');
        };
    }

    return FirstClass;

});


/Services/SecondClass.js:
'use strict';

define([], function () {

    function SecondClass() {
        this.saySomething = function () {
            alert('yo!');
        };  
    }

    return SecondClass;

});


That's it! It's easy to use RequireJS


On next post, I'll show you how RequireJS can be used for dynamically assigning controller to AngularJS routing


Happy Coding! ツ