Tuesday, June 5, 2012

Basic Javascript & MVC Best Practices

Basic JavaScript & MVC Best practices:

JavaScript is fundamentally about objects. Arrays are objects. Functions are objects. Objects are objects. So what are objects? Objects are collections of name-value pairs. The names are strings, and the values are strings, numbers, booleans, and objects (including arrays and functions). Objects are usually implemented as hash tables so values can be retrieved quickly. [ Douglas Crockford]

Blindly applying a “best practice” is just as irresponsible as never applying a “best practice”, but asses the trade before you commit to any implementation.

Shoot for library or framework:

• Make your script as Generic as possible
• Foster Code reuse
• Make functions self-sufficient (Message based over Address Based communication)
• Stay away from global variables , stop polluting the global name space

  • o myglobal = "hello"; // antipattern
  • o console.log(myglobal); // "hello"
  • o console.log(window.myglobal); // "hello"
  • o console.log(window["myglobal"]); // "hello"
  • o console.log(this.myglobal); // "hello"

  • o Rule of thumb: always declare variables with var
  • o Name pollution prohibits portability or reuse

• Never write a function within the default namespace(window)
• Determine if the object should be a singleton or instance based
• Capitalizing Constructors for readability
• Writing Comments helps
• Avoid Heavy nesting
• Optimize loops (Specially DOM manipulations, for loop .length is tricky )

Never write JavaScript inside a view

• Writing JavaScript inside a partial view makes your code obtrusive and gives your fellow developer s hard
time when troubleshooting dynamic behaviors and degrades performance as js is not cached
• Writing JavaScript inside a view degrades reuse if not make it next to impossible

Never hardcode string or label or title inside a view
• Makes globalization a lot more difficult

Please do not store a string literal inside a JavaScript
• Literal can be a basic default value( like ‘Enter Value’)
• Literal can be a business rule message
• Notification title etc.

Do not use View Data (View Bag) if possible but instead stick with ViewData.Model
• In complex page figuring out the why the data is required is not an easy task

Think twice before formatting any value
• Date
• Currency
• Numbers

Learn when to use Ajax vs regular request and Get vs Post
• Http requests are expensive make sure your afford it, there is no one to bail you out

Use Action Filters for cleaning controller actions
• Actions filters are one good way of code reuse between Controller actions

Do not stuff Controller Actions with Logic (Separation of Concern rules)
• Fosters unit testing

Never keep logic inside a View but instead create a reusable Html Helper
• Duplicating a logic inside a view will eventually lead to issues
• Duplicating a helper makes maintenance a breath and promotes reuse

Examples: The following code was repeated three times in my current App.

<%if ((Model.Campaign.IsLaunchable) && Model.Campaign.IsAuthorized && (!Model.Campaign.IsPaused) && canLaunchCampaign)
<a href="#" class="t-button t-state-default updateOptimizer" campaign="<%:Model.Campaign.CampaignId%>"
message="Please complete all required sections in order to reserve this campaign." actualaction='<%=Url.Action("Wizard", "Activation", new { area = "Customer", id = Model.Campaign.CampaignId })%>'
updateaction="<%=Url.Action("UpdateOptimizer","Campaign",new {area="Customer",planId=Model.PlanId})%>"
confirmaction="<%=Url.Action("GetCampaign","Campaign",new {area="Customer",id=Model.Campaign.CampaignId,actionRequested="launch"})%>">
<%} %>

And Has Now become:

<%=Url.If(Model.Campaign.ShowLaunch, url => url.Launch(Model.Campaign.CampaignId, Model.PlanId))%>

I have seen href=”#” in <a> tag causing issues several times, understand what it means

• Defines a local navigation(jumps to the top of the page )
• Why is it an anchor if you do not use the href (better be a button)
• Href=”#self” Could help
• Or href=”javascript:void(0)”…obtrusive but works
• Href=”#” but you should remember to return false from all functions
• e.preventDefault();

DON'T overuse session; instead use TempData for short lived (intra-request) storage.
• Degrades performance
• TempData for intra request data

Hiding a link from user view does not make a resource unreachable