Javascript Tips: Carefully use "this" when writing classes, else you may cause memory leak.

Lets say we want to declare a class in Javascript, which is equivalent to the following C# class.

public class Student
{
  public string FirstName = “”;
  public string LastName = “”;

  public Student( string firstname, string lastname)
  {
    this.FirstName = firstname;
    this.LastName = lastname;
  }
  
  public string GetFullName()
  {
    return FirstName + LastName;
  }
}

To write a similar class in JavaScript we can do something like the following [ but this will create memory leak, I am explaining that in a moment ]

function Student ( firstname, lastname)
{
  this.FirstName = firstname;
  this.LastName = lastname;

  this.GetFullName = function()
  {
    return this.FirstName + this.LastName;
  }

}


now in C# if we want to instantiate an object of Student and want to call the GetFullName() method, we do the following.
Student student = new Student(“Shahed”, “Khan”);
string fullname = student.GetFullName();


and we can create as many objects as we want and call its methods, each of the object will maintain its own state, and all objects will use the same copy of the GetFullName()  method.

But Javascript has different behaviour when we do the following on the above Javascript class.

var student = new Student(“Shahed”,“Khan”);
car fullname = student.GetFullName();


In Javascript, functions are treated as variables as a result when we create a new object of Student it creates  new sets of firstname, lastname and also a new copy of GetFullname method, as a result we are creating memoryleak.

Do not worry too much, there is a workaround for this, lets redefine the class in a different way.

function Student ( firstname, lastname)
{
  this.FirstName = firstname;
  this.LastName = lastname;

  this.GetFullName = GetFullName;

}

function GetFullName()
{
  return this.FirstName + this.LastName;
}



Notice I have moved the GetFullName function out of the class, and for this tweaking all new objects of the Student class will share the same instance of of GetFullName method and avoid memory leak.

Thank you for being with me so far.


Updated 24th Feb
===============
Laurent from Galasoft gave some good feedback, 
JavaScript object oriented should be done by modifying the prototype property of the object, and never by storing methods using the “this” keyword. The workaround provided above is not good practice, as it forces the use of a global function. We should always declare methods in JavaScript object like this:
 
function Student(firstName, lastName)
{
 this.firstName = firstName;
 this.lastName = lastName;
}


Student.prototype =
{
 getFullName : function()
 {
   return this.firstName + ” ” + this.lastName;
 }
}

also note correct naming convension, ( Javascript follows Java notation not C#). For JavaScript best practices please refer to the work of Microsoft Silverlight team.

Solving DNN deployment issues, Redirecting to localhost and Running DNN in a different port

I was trying to host a small DNN application in one of our Server and I was facing couple of  issues.

Problem 1:
The first problem I faced is it was always redirecting to localhost, whenever I tried http://domain.com/dnn it was redirecting to http://localhost/dnn as a result the site was un-accessible from outside.


Solution

This was easy to solve.
1. I needed to log in as host account.
2. Then I needed to go to the Admin > Site Settings page
3. And finally In the Portal Alias section I added a new Http Alias “domain.com/dnn”

This solved my problem when I hosted the site in port 80.

clip_image002[14]

Problem 2:

Now I tried to host the application in a different port 8080. I.e. http://domain.com:8080/dnn. and somehow when I clicking to redirect to any other page the port started to disappear. The http://domain.com:8080/ automatically turned to http://domain.com/ .

Solution

After googling and looking at the web.config carefully I found, its clearly documented in web.config that

<!– set UsePortNumber to true to preserve the port number if you’re using a port number other than 80 (the standard)
    <add key=”UsePortNumber” value=”true” /> –>

clip_image002[12]

I tweaked my appsettings section  and added the magic key

<add key=”UsePortNumber” value=”true” />

Also I had to add a new Http Alias “domain.com:8080″

This solved my problem and started retaining the port for my http://localhost:8080 but not http://domain.com:8080.  The http://domain.com:8080 was still turning to http://domain.com

Note: I later discovered this was not a problem of DNN and the issue happened because of the setup of our router settings and port forwarding, which I’ll discuss next.


Problem 3: 
Even after adding the “UsePortNumber” key it did not solve my problem

Solution

Our Router was Port Forwarding all traffic of 8080 to the port 80 of the machine where DNN app is hosted. I.e. 8080 –> 80. As a result even from a browser I as typing http://domain.com:8080 , the DNN Request object was getting http://domain.com and when DNN handlers and url rewriters spitting the reformatted url it was spitting http://domain.com.

This was a big problem for me, initially I thought I would write a HttpHandler for 404 page not found, but soon realized it will never hit the server with the spitted Url so that didn’t work. Then I thought I would tweak the DNN handlers to handle this scenario, but later tweaked the IIS and Router to handle this.

1. In IIS I added, support for 8080  to my Default Website.

 

clip_image002

 

2. In Router instead of forwarding to port 80 I started forwarding 8080 to 8080.
3. Made sure that in my DNN Site Settings, I have added Http Alias “domain.com:8080/dnn”.

Waaa la, This solved my issue.

Hope this helps and Thank you for being with me so far.

LINQ Tips: Implementing IQueryable Provider

Check out the following from Matt Warrens blog posts, if you are interested on how to implement IQueryable Provider.

source: http://blogs.msdn.com/mattwar/archive/2007/07/30/linq-building-an-iqueryable-provider-part-i.aspx

Part I – Reusable IQueryable base classes
Part II – Where and reusable Expression tree visitor
Part II – Local variable references
Part IV – Select
Part V – Improved Column binding
Part VI – Nested queries
Part VII – Join and SelectMany

LINQ Tips: Querying ArrayList via LINQ

Problem
If you try to query an ArrayList via LINQ you might be surprised to see that its not supported and throwing an exception. In other words the following query will not work at all.

ArrayList students = GetStudents();
var query =
  from student in students
  where student.Score > 80
  select new { student.ID, student.Name };


Cause
The problem comes from the fact that LINQ to Objects has been designed to query generic collections that implement the System.Collections.Generic.IEnumerable<T> interface. Where an ArrayList is a nongeneric collection that contains a list of untyped objects and also does not implement IEnumerable<T>.

Solution
Cast operator comes into rescue.

Here is the signature of the Cast operator:
public static IEnumerable<T> Cast<T>(this IEnumerable source)

Cast can take a nongeneric IEnumerable and returns a generic IEnumerable<T>.
A modification of the above query like this will solve the problem and you will be able to query ArrayList via LINQ.

ArrayList students = GetStudents();
var query =
  from student in students.Cast<Student>()
  where student.Score > 80
  select new { student.ID, student.Name };

LINQ Tips: Querying disposable objects in an using block

Be careful while querying the disposable object inside an using block, you may find that the yielded objects are all disposed before you have used them. To get over this issue use the ToList() method. You can exit the using block, and yield the results out.

Example:

IEnumerable<Student> results;
using (var db = new StudentDataContext())
{
  results = db.Students.Where(…).ToList();
}
foreach (var student in results)
{
  SomeMethod(student);
  yield return student;
}