Thursday, December 24, 2015

AngularJS - Broadcasting and Emitting Events

AngularJS Scope provides support to broadcast events and handle them. We may want to wait for an event to execute some other activity, e.g. waiting for particular data to be received from an AJAX request.

AngularJS provides two types of events generation:

  1. Emitting - propagates the event upwards in the scope hierarchy.
  2. Broadcasting - propagates the event downwards in the scope hierarchy.

Emitting:

The $scope contains a function $emit() that is used to propagate an event upwards in the scope hierarchy. First parameter of this function is the name of the event that is being emitted, after first parameter we can pass multiple parameters for different purposes, but typically we want to pass data which should be shared with the event listeners.

Broadcasting:

The $scope contains another function $broadcast() this will be used to propagate the event downwards in the scope hierarchy. Contains the same parameters as with $emit function, first parameter will be the event's name, and in the second parameter we can pass our data which should be shared by event listeners.

Controllers can register for the event by using notification function $on() which will be called when the event occurs.

Let's see this example:

demoApp.controller('Controller1', function ($scope, $rootScope, $timeout) {

    $scope.title = 'Controller1';
    $scope.showEvents = false;

    $scope.sendMessage = function () {

        $scope.$broadcast('Controller1_Event_Broadcast', 'Hi from Controller1');
        
        $scope.showEvents = true;
    };

    $scope.$on('Controller2_Event_Emit', function (event, data) {

        console.log('I am ' + $scope.title + ', Controller2_Event_Emit received with data: ' + data);

    });
});

demoApp.controller('Controller2', function ($scope) {

    $scope.title = 'Controller2';

    $scope.$on('Controller1_Event_Broadcast', function (event, data) {

        console.log('I am ' + $scope.title + ', Controller1_Event_Broadcast received with data: ' + data);

        $scope.$emit('Controller2_Event_Emit', 'Hi from Controller2');
    });
});

And in html, the controllers hierarchy should be setup as, Contrller2 should be nested in inside Contrller1's tag. e.g:

Check browser's console to see event messages

we have two controllers, Controller1 will broadcast an event (Controller1_Event_Broadcast) using $scope.$broadcast() function, with string data ('Hi from Controller1'). And Controller2 has registered this event with $scope.$on(), where second parameter 'data' contains the value what we passed when this event is raised. Inside the receiving handler of Controller1_Event_Broadcast event, Controller2 is emitting its own event(Controller2_Event_Emit) with $scope.$emit() function. This emitted event also have a handler defined in Controller1 to receive notification from Controller2 for this event.

In this example we have seen how a Parent controller can broadcast its events to downwards to its children controllers, and how a child controller can emit its events upwards to its parents in the hierarchy.

Events with $rootScope:

But how if both these controllers as siblings to each other, and we may want to raise a global event that both these controllers should be able to handle, because so far we have seen how to handle events either from parent or either from child controllers. So here comes the role of $rootScope, as we know all controllers can access the $rootScope's contents. So in case of siblings controllers, if we want to raise an event that should be handles by all sibling controllers then we have to broadcast that event on the $rootScope. Look at this example:

$scope.sendMessage2 = function () {
       
        $rootScope.$broadcast('RootScope_Broadcast_Event', 'Hi from Controller1 via $rootScope');        
       
    };

Added another function sendMessage2() in Controller1, when this function is called, its broadcasts RootScope_Broadcast_Event event on $rootScope. And all interested controllers can register for this event using the same $on() function, like:

$scope.$on('RootScope_Broadcast_Event', function (event, data) {

        console.log('I am ' + $scope.title + ', RootScope_Broadcast_Event received with data: ' + data);

    });    

Monday, December 14, 2015

MS SQL - How to loop through table rows in T-SQL

In this post we will see three ways to iterate through table rows in a loop using T-SQL. I am using Microsoft SQL SERVER 2008 R2. Let first setup a target table we want to iterate rows. Create a new table (say Items) in database, with the following script.
--Create Table
CREATE TABLE [dbo].[Items](
 [Id] [int] IDENTITY(1,1) NOT NULL,
 [Item_Code] [nvarchar](255) NOT NULL,
 [Item_Name] [nvarchar](255) NOT NULL,
)
Populate Items table with some dummy records.
SET IDENTITY_INSERT [dbo].[Items] ON
INSERT [dbo].[Items] ([Id], [Item_Code], [Item_Name]) VALUES (1, N'I001', N'Item1')
INSERT [dbo].[Items] ([Id], [Item_Code], [Item_Name]) VALUES (2, N'I002', N'Item2')
INSERT [dbo].[Items] ([Id], [Item_Code], [Item_Name]) VALUES (3, N'I003', N'Item3')
INSERT [dbo].[Items] ([Id], [Item_Code], [Item_Name]) VALUES (4, N'I004', N'Item4')
INSERT [dbo].[Items] ([Id], [Item_Code], [Item_Name]) VALUES (5, N'I005', N'Item5')
INSERT [dbo].[Items] ([Id], [Item_Code], [Item_Name]) VALUES (6, N'I006', N'Item6')
INSERT [dbo].[Items] ([Id], [Item_Code], [Item_Name]) VALUES (7, N'I007', N'Item7')
INSERT [dbo].[Items] ([Id], [Item_Code], [Item_Name]) VALUES (8, N'I008', N'Item8')
INSERT [dbo].[Items] ([Id], [Item_Code], [Item_Name]) VALUES (9, N'I009', N'Item9')
INSERT [dbo].[Items] ([Id], [Item_Code], [Item_Name]) VALUES (10, N'I010', N'Item10')
SET IDENTITY_INSERT [dbo].[Items] OFF

Using Cursor
This is the first way we are iterating table rows using CURSOR. For the scope of example I am using only top 10 records in these scripts, you can change according to your requirements. Here is the first loop:
  
--Using Cursor
DECLARE @MyCursor CURSOR;

--sample variables to hold each row's content
DECLARE @ItemID int;
DECLARE @ItemCode varchar(255);
DECLARE @ItemName varchar(255);

BEGIN
    SET @MyCursor = CURSOR FOR
    select top 10 
    Id, Item_Code, Item_Name 
    from dbo.Items

    OPEN @MyCursor
    FETCH NEXT FROM @MyCursor
    INTO @ItemID, @ItemCode, @ItemName

    WHILE @@FETCH_STATUS = 0
    BEGIN
    
  --Your logic here...
  --just printing in the loop
  print 
   'ItemID=' + Cast(@ItemID as varchar(255)) +
   ', ItemCode=' + @ItemCode + 
   ', ItemName=' + @ItemName   
   
   
  FETCH NEXT FROM @MyCursor
  INTO @ItemID, @ItemCode, @ItemName      
  
    END; 

    CLOSE @MyCursor ;
    DEALLOCATE @MyCursor;
END;
Fetching the desired records in cursor and check in the while loop until we get @@FETCH_STATUS = 0. Inside the loop you can put your logic what you want to do with each row's contents. In this example I am using three variables ItemID, ItemCode and ItemName and populating their values from each row content. Then I am just printing these to see the results.

Using temp table (using unique integer key)
Second method is to use temp table that already have a column with unique int key.
--Using #tempTable while target table has an int Unique key
select top 10 
Id,Item_Code, Item_Name
into #tempTable 
from dbo.Items

--sample variables to hold each row's content
DECLARE @ItemID int;
DECLARE @ItemCode varchar(255);
DECLARE @ItemName varchar(255);

while exists (select * from #tempTable)
begin

    select top 1 
     @ItemID = Id
    ,@ItemCode = Item_Code
    ,@ItemName = Item_Name
    from #tempTable
    order by Id asc

    --Your logic here...
 --just printing in the loop
 print 
  'ItemID=' + Cast(@ItemID as varchar(255)) +
  ', ItemCode=' + @ItemCode + 
  ', ItemName=' + @ItemName 


    delete #tempTable where Id = @ItemID

end

drop table #tempTable
In this technique, we are extracting the desired records in a temp table. In the while condition we are checking if there is any record exists in this temp table then continue looping, and within the loop we are selecting top 1 single record, extract its content, put our logic, and then in the end, we can simply delete the current row from temp table. So finally we will get all rows processed and deleted from temp table.

Using temp table (adding new identity key)
Third technique is to use temp table, and add an IDENTITY field in temp table, to uniquely identify each row.
--Using #tempTable and have created own Identity ID
SELECT 
TOP 10
IDENTITY(INT, 1,1) AS TempID,
Item_Code, Item_Name
INTO #tempTable
FROM dbo.Items 

--sample variables to hold each row's content
DECLARE @ItemCode varchar(255);
DECLARE @ItemName varchar(255);

--helper variables used for looping purpose
DECLARE @MaxTempID int;
DECLARE @CurrentTempID int;

SELECT @MaxTempID = MAX(TempID) from #tempTable
SELECT @CurrentTempID = MIN(TempID) from #tempTable

WHILE @CurrentTempID <= @MaxTempID
BEGIN

    -- Get one record
    SELECT TOP 1 
    @ItemCode = Item_Code
    ,@ItemName = Item_Name
    FROM #tempTable
    WHERE TempID = @CurrentTempID

     --Your logic here...
 --just printing in the loop
 PRINT
  'ItemCode=' + @ItemCode + 
  ', ItemName=' + @ItemName 

    SELECT @CurrentTempID = @CurrentTempID + 1
END

In this method, before starting loop we extract the maximum and minimum values of identity column(that we added) in variables to use for looping conditions. Inside the loop we are extracting each row's content by that unique identity value.

Wednesday, December 9, 2015

AngularJS - Defining Custom Directives Part IV

AngularJS custom directives series previous articles:

In this post I will discuss isolate scope with local scope properties.

To interact with outside world while using isolated scope, angular provides three options which are known as Local Scope Properties, and used with @,= and & characters.

The local scope option @ is used to access string values that defined outside the directive scope. It can be understand as a function accepting a single string parameter. In the following directive example scope is received a string variable and named it as myLocalName inside directive scope (although you can use the same name as passed through directive, but here I used a different name to make it more clear).

demoApp.directive('directiveWithIsolateScopeRecevingStringParameter1', function () {
 return {
  scope: {
   myLocalName: '@'
  },
  template: 'Item name received from parameter: name = {{myLocalName}}'
 };
});
Directive Implementation:
Note that the attribute name we used here, is following the same naming scheme as we used while defining custom directive, i.e. camelCase. In my-local-name attribute we are passing a string item.name from controller's property. We can also use different names inside directive scope and directive implementation, look at this example:
demoApp.directive('directiveWithIsolateScopeRecevingStringParameter2', function () {
 return {
  scope: {
   myLocalName2: '@myLocalName'
  },
  template: 'Item name received from parameter: name = {{myLocalName2}}'
 };
});
Directive Implementation:

Here in implementation we define attribute named my-local-name, but inside directive scope we are using different name my-local-name2.

Values passed by @ option is not sync with outside scope, i.e. if item.name value changes from outside of directive then directive get updated value, but if the value is being changed inside the directive scope then item.name property will not be affected.

If you want two-way binding then you have to use second scope option '=' character, it will keep the directive variable in-sync with outside world. Example:

demoApp.directive('directiveWithIsolateScopeBindedToObject', function () {
 return {
  scope: {
   myBindedItem: '='
  },
  template: 'Item from isolate scope binded to object in parent controller: name = {{myBindedItem.name}}, category = {{myBindedItem.category}} '
 };
});
Directive Implementation:
    
The last scope binding option & is used to bind external functions. You can think of it as accepting a function delegate, then you can call it like a regular function. For example we can pass a function name, of the controller, which we want to be called on some specific event e.g. click event. When you click an element of the directive, it will call that external function, and controller can define its own logic being invoked from inside the directive.
demoApp.directive('directiveWithIsolateScopeCallingParentFunction', function () {
            return {
                scope: {
                    myFunction: '&'
                },
                template: 'Click this button, it will call a function in parent controller:  '
            };
        });
Directive Implementation:
Here we are passing a function name doSomeWork() in the attribute my-function, and within the directive scope we are accepting this function with & option in our local variable myFunction. Then we are calling this function from the click event of the button defined in the template content of directive.

AngularJS - Defining Custom Directives Part III

After last 2 posts, we are now familiar with developing AngularJS custom directives. If you have not read old posts, I recommend to first take a look on these. In this post I will discuss the scope object inside the custom directive. By default, a directive have access to the parent scope. In the html markup where the directive is placed, it will get access to the scope object of the parent controller. For example in the following directive we can access an item property which is defined in the scope of the parent controller.
demoApp.directive('directiveUsingParentScope', function () {
    return {
        template: 'Item from parent controller: name = {{item.name}}, category = {{item.category}} '
    };
});
Directive Implementation:
Sorry for the long directive names I used in these examples, these are for demonstration purpose to make it more understandable.
This directive will render the name and category properties of item object defined in parent controller. But the limitation here is that the directive is totally depends on the parent controller and if you place directive some where outside of the scope of parent controller, it will not work as expected.
To make a directive more reusable and removing dependency on the parent scope we can isolate it. For this we have to define scope object in the directive declaration. In following example directive is defined with an empty object assigned to its scope, so this directive is no longer have direct access to the parent scope, and would not render the item's name and category.
demoApp.directive('directiveWithIsolateScope', function () {
    return {
        scope: {},
        template: 'Item from isolate scope: name = {{item.name}}, category = {{item.category}} '
    };
});
Directive Implementation:
But angular provides access to another object named $parent, through which we can access parent scope even inside an isolated directive. See this example:
demoApp.directive('directiveWithIsolateScopeAccessingParent', function () {
    return {
        scope: {},
        template: 'Item from isolate scope accessing parent scope: name = {{$parent.item.name}}, category = {{$parent.item.category}} '
    };
});
Directive Implementation:
This directive scope is isolated and have nothing to interact with outside world, but in the template content we are accessing the item property of the parent controller by using $parent object.

Tuesday, December 1, 2015

AngularJS - Defining Custom Directives - Part II

In last post we have seen how to create a basic custom directive in AngularJS, we have used three properties i.e. restrict, template and transclude. Let explore some more features AngularJS provides while using cutom directives. In this post I will focus on templateUrl and the link function.

Template / TemplateUrl Properties: 
We can define the DOM elements to be replaced through the template or templateUrl properties. We have seen an example for template property in the last post, let try options with templateUrl property. At a fundamental level we can use the template property to define our directives content as inline string. As in example below:
validationApp.directive('directiveWithInlineString', function () {
    return {
        restrict: 'EA',
        template: 'Hello from the Directive-With-Inline-String Template', 
    };
});
Next thing we have is the templateUrl property which gives us more flexibility in writing tempaltes. We can use templateUrl in multiple ways.

First method is write html content in a file placed on server, and put that file's url in templateUrl property. For exmaple create file named 'htmlTemplate1.html' and put the following content and save it.
<h3>My Heading</h3>
<p>Hello from the Directive-With-Url Template</p>
Now we can use this file as directive template by putting file url in templateUrl property.
validationApp.directive('directiveWithUrl', function () {
    return {
        restrict: 'EA',
        templateUrl: 'views/htmlTemplate1.html'        
    };
});
This will look for a file 'htmlTemplate1.html' inside 'views' folder and load it as the content of element that imeplemented this directive.

Second method is to write html content within the script tag, with type = 'text/ng-template' and a unique id for our template.
<script type='text/ng-template' id='key_for_template_in_script_tag'>
     <p>Hello from the Directive-With-Template-Key-In-Script-Tag</p>
</script>
Here I defined id='key_for_template_in_script_tag' to uniquely identity the template, now next thing is use this template and for this we have to simply put this key name in the templateUrl property. As in example below:
validationApp.directive('directiveWithScriptTag', function () {
    return {
        restrict: 'EA',
        templateUrl: 'key_for_template_in_script_tag'
    };
});
Just make sure that you place the directive tempalte first, before its implemenation when loading your page.

Third method is to place the template in the cache object used by Angular called the $templateCache. Same like we defined a unique key to template definition in the script tag, we have to label the template for identification. To place things in $templateChache we have to use run function on the module.
validationApp.run(function ($templateCache) {
    $templateCache.put('key_for_template_in_templatecache', 'Hello from the Directive-With-Template-Key-In-TemplateCache');
});
First argument of put function is the key we want to define for template and second argument is the actual content we want to use. We can implement this template in the same way as we did in script tag method.
validationApp.directive('directiveWithTemplateCache', function () {
    return {
        restrict: 'EA',
        templateUrl: 'key_for_template_in_templatecache',
    };
});
Link function: 
Link function will be used to make DOM elements dynamic. Angular runs a link function for each directive and attach event liseners on the DOM elements, this way we can keep the view and model in sync making it more interactive. Let create a directive with link function to transform text between upper case and lower case with mouse movement.
validationApp.directive('directiveWithLinkFunction', function () {
    return {
        restrict: 'EA',

        link: function ($scope, element, attrs) {

            element.bind('mouseenter', function () {
                element.css('text-transform', 'uppercase');
            });
            element.bind('mouseleave', function () {
                element.css('text-transform', 'lowercase');
            });
        }
    }
});
Inside the link function, we are receiving our DOM element in the parameter 'element' , we can attach events, makes changes or write validation logic etc. In this example we are attaching the CSS class to the element to transform text between upper case and lower case.

That's it, its pretty easy making custom directives with even dynamic behavior. I hope you enjoyed this post and learned something useful. I the next post, I will discuss about the scope options we can use in custom directives.