Wednesday, July 29, 2015

Prevent Flickering of AngularJS page load using ng-clock

Flickering is a common problem of DOM manipulation using AngularJS. If page is huge then it shows “{{}}” braces before manipulation of DOM. Anyway, the solution is very simple.

ng-cloak directive was added to Angular in order to prevent the flickering of elements before your application has fully loaded. It then removes ng-cloak once it has had a chance to compile your 
views.

      1)      Add ng-clock directive to your page root element. One perfect position may be <body> tag of page or root <div> element.
<div ng-cloak>

      2)      Apply below style sheet to apply style of ng-clock class.  

<style>
    
[ng:cloak],
[ng-cloak],
[data-ng-cloak],
[x-ng-cloak],
.ng-cloak,
.x-ng-cloak {
  display: none !important;
}
</style>

       And your problem is solved !.


Sunday, July 19, 2015

Return multiple result set using DataReader and Entity Framework

We know th NextResult() function of Reader Object which is part of ADO.NET library. Using this mechanism we can read more than one entity in a single database class. Is there any way to read more than one entity on top of Entity Framework? Yes, we can implement same mechanism in EF too. 

DbContxt API does not support this operation directly so, we have to cast database object to ObjectContext to enjoy this facility.

Here is sample code implementation for same.
   
            var db = new ApplicationDbContext();
            var cmd = db.Database.Connection.CreateCommand();
            cmd.CommandText = "YourStoredProcedure";
            cmd.CommandType = System.Data.CommandType.StoredProcedure;
            cmd.Parameters.Add(new SqlParameter("@param", Id));
           
            try
            {

                db.Database.Connection.Open();

                var reader = cmd.ExecuteReader(System.Data.CommandBehavior.CloseConnection);

                var objectContext = ((IObjectContextAdapter)db).ObjectContext;

var Modl1 = objectContext.Translate<Model1>(reader, "Model1",         MergeOption.AppendOnly).FirstOrDefault();

                reader.NextResult(); 

              var Model2 = objectContext.Translate<Model2>(reader, "Model2",                   MergeOption.AppendOnly).FirstOrDefault();

            }
            finally
            {
                db.Database.Connection.Close();
            }

Translate<T>  function will transferred return Entity to T model. Now, the question is if the result type id single valued?

Say, for example, the query is something like this.
Select count(*) from Table.

It will return some integer value in result. In this case the T value should be integet

               var Model2 = objectContext.Translate<int>(reader).FirstOrDefault();

and no need to supply model name more.

Please make sure Model1 and Model2 are property of Context class which is inherited from DbContext.


Wednesday, July 15, 2015

Skip Authorization for AllowAnonymous Attribute in Custom Authorization filter

If you use custom Authorization, attribute in controller level and want to allow any action for anonymous user then maybe you have face this issue already or searching for solution.

Yes, If you implement your own authorization mechanism by inheriting AuthorizeAttribute class and at same time allow any action by decorating “AllowAnonymous “ , it will not work.

To make it work, we have to add little spice in custom authorization filter class. Here is my example where I am bypassing authorization challenge if the action or controller has “AllowAnonymous” attribute.

public override void OnAuthorization(AuthorizationContext filterContext)
        {

            bool skipAuthorization = filterContext.
                                                    ActionDescriptor.
                                                    IsDefined(typeof(AllowAnonymousAttribute), true)
                                                    ||                      filterContext.ActionDescriptor.
                                                     ControllerDescriptor.
                                                    IsDefined(typeof(AllowAnonymousAttribute), true);

            if (skipAuthorization)
            {
                return;
            }


            if (filterContext.HttpContext.Request.IsAjaxRequest())
            {
                if (!filterContext.HttpContext.User.Identity.IsAuthenticated)
                {
                    filterContext.HttpContext.Response.StatusCode = 401;
                    filterContext.Result = new HttpStatusCodeResult(401, "Please login to continue");
                    filterContext.HttpContext.Response.End();

                    //FormsAuthentication.SignOut();
                }
            }
        }


The solution is very simple. Just w are checking the action or controller containing AllowAnonymous attribute or not? If so, then we are returning flow from there by skipping authorization challenge. 

Saturday, July 11, 2015

Is $scope.$apply() is anti pattern ?

I personally think it’s not anti pattern. As, we know anti pattern implies some technique/ implementation which may solve your current problem but may introduce another big problem for future. So, If we think in this angle $scope.$apply() is not at all harmful or I think there is almost zero chances that it will inject  something wrong in your design flow.

Let’s understand why people use $scope.$apply ! Me too was thinking why to use $scope.$apply ? when AngularJS provides in-built mechanism of model binding ?

Yes, AngularJS has capability of automatic model binding if data comes from AngularJS environment.  If not, then sometimes automatic model binding fails.

From my personal experience I have seen, people are very much handy with $.ajax() function of JQuery to perform AJAX call and this practice may lead you to use $scope.$apply() frequently.  This is one typical situation based on my observation.  So, the core concept is that, If data triggers from non Angular environment then to bind the data to model, we have to trigger $scope.$apply(to execute digest mechanism forcefully) .

Here is one small example where we are using timeout function of JavaScript creates non angular environment.

  setTimeout(function () {
                $scope.message = 'Timeout';
            }, 1000);

This will not work because setTimeout() will try to digest message model after one second but as the mechanism is outside of Angular scope it will not update view with Timeout message.
Now, here is the mechanism to call digest cycle forcefully.

    setTimeout(function () {

                $scope.message = 'Timeout';

               //Call digest cycle forcefully
                $scope.$apply(function () {});
            }, 1000);


Now, one common error you may encounter is “digest already in progress” .This may occur If you try to call digest forcefully within another digest cycle. So, the below code will throw exception surely.

                $scope.$apply(function () {
                    $scope.$apply(function () {
                        $scope.message = "Timeout called!";
                    })
                });

The reason is , we are calling $scope.$apply() within another same.



Sunday, July 5, 2015

Include dependent entity in Repository Generic Repository Pattern.

Sometime you may come across with the error that “Data reader associated with open connection which must be close first”

This error is because of lazy loading in Entity Framework. Sometime we use navigation property to read column from child table in time of parent table fetch. Just have a look on below query.

var result = (from m in UnitOfWork.GetRepository<TABLE_A>().Where(f => f.MasterCollegeId == Id)

                          select new SOME_DTO
                          {
                              CompanyId = m.CompanyId,
                              CompanyLogo = m.CompanyMaster.CompanyLogo,
                              CompanyName = m.CompanyMaster.CompanyName,
                             
                          }).ToList();

Here TABLE_A is parent table and “CompanyMaster” is child table(which we are not seeing in Include) and in time of select query generation we are taking “CompanyLogo” and “CompanyName” column which belongs to “CompanyMaster” table.

Now, If we try to serialize result in another layer, It may throw “Connection associated with data reader is open which need to close first” this exception.

This is Just because we did not include the dependent entity in Query. Here is solution with respect of Repository/Generic Repository pattern.

Step 1 ) Just Get DbSet object from Repository.

public virtual DbSet<T> GetQueryable()
        {
            return _dbset as DbSet<T>;
        }

In case of Generic Repository, we have to return DbSet<T>.

Step 2) Add Include entity using Include() function. Here is modified query.

var result = (from m in UnitOfWork.GetRepository<TABLE_A>().GetQueryable().Include("CompanyMaster").Where(f => f.MasterCollegeId == Id)

                          select new SOME_DTO
                          {
                              CompanyId = m.CompanyId,
                              CompanyLogo = m.CompanyMaster.CompanyLogo,
                              CompanyName = m.CompanyMaster.CompanyName,
                             
                          }).ToList();



And your problem has solved. J

Saturday, July 4, 2015

Ajax Call by search string in Select2 auto complete

Select2 is nice Javascript plug in to create dropdown which supports lot of event and very much flexible too.  Few days ago I got requirement where I had to create one dropdown with search facility . I mean we need to pull data based on search string of user and bind to dropdown.

Select2 support ajax functionality too. Here is sample code to implement ajax


$(document).ready(function () {

                                var pageSize = 20;

                                jQuery(".select2").select2({
                                    placeholder: "Select value ...",
                                    allowClear: true,
                                    ajax: {
                         //How long the user has to pause their typing before sending the next request
                                        quietMillis: 150,
                                        url: '../CollegePlacement/Result',
                                        data: function (term, page) {
                                            return {
                                                pageSize: pageSize,
                                                pageNum: page,
                                                searchTerm: term
                                            };
                                        },
                                        results: function (data) {

                                            return {
                                                results:
                                                    data.map(function (item) {
                                                        return {
                                                            id: item.Id,
                                                            text: item.CompanyName
                                                        };
                                                    }
                                            )
                                            };

                                        }
                                    }
                                })

                            });


Please have a look on result callback of function. The column name which is coming as collection has Id and CompanyName field. We are just mapping this with default column name of select2 which is “id” and “text”


Here is sample output.