KEMBAR78
That’s not your var – JavaScript best practices for C# developers | PPTX
That’s not your var –
JavaScript best practices for C# developers
György Balássy
balassy@aut.bme.hu
Zoltán Dávid
david.zoltan@aut.bme.hu
2
A long time ago in a galaxy far, far away…
App
dev
Server side
dev
Web
dev
?
3
Note: this image is machine-translated from Hungarian!
http://html5jatekok.hu
Real World HTML5 and MVC – Lessons Learned
Tomorrow 15:45-16:45 in Room 2
5
Today…
Are we ready?
6
Rich client applications
HTML markup CSS styles JavaScript code+ +
How to style and code against new HTML elements,
if the browser does not even understand them?
html5shim / shiv / boilerplate Modernizr
7
Feature detection
// DON'T USE THIS: Detecting specific browsers („UA sniffing”)
if(navigator.userAgent.indexOf("MSIE") == -1) {
window.addEventListener("load", myFunc, false);
} else {
window.attachEvent("onload", myFunc);
}
// DO USE THIS: Detect feature
if(window.addEventListener) {
window.addEventListener("load", myFunc, false);
} else if(window.attachEvent) {
window.attachEvent("onload", myFunc);
}
9
Modernizr – http://modernizr.com
audio.src = Modernizr.audio.ogg ? 'background.ogg' :
Modernizr.audio.mp3 ? 'background.mp3' :
'background.m4a';
.no-boxshadow div.button { background:transparent url(btn.png) 0 0; }
.boxshadow div.button { box-shadow:inset 1px 1px 2px #ccc; }
JavaScript:
CSS:
10
Modernizr – http://modernizr.com
Modernizr.load({
test: Modernizr.geolocation,
yep : 'geo.js',
nope: 'geo-polyfill.js'
});
Resource loader:
„polyfill (n): a JavaScript shim that replicates the standard API for older browsers”
https://github.com/Modernizr/Modernizr/wiki/HTML5-Cross-browser-Polyfills
11
DEMO
Audio in all browsers
12
Structuring your code
DON’T make your variables and functions global!
DO USE namespaces!
var NS = NS || {};
NS.myFunc = function(){ … }
13
DEMO
Structural patterns
16
Script# by Nikhil Kothari
http://projects.nikhilk.net/ScriptSharp
Source files
(.cs)
Referenced
assemblies
(.dll)
Script#
compiler
(ssc.exe)
C#
compiler
(csc.exe)
Generated
assembly
(.dll)
Generated
script
(.js)
Associated
script
(.js)
Dev Machine/Build Process Deployed App
17
Code quality and consistency
Code Analysis
(FxCop)
Source Analysis
(StyleCop)
JSLint
JSHint
Warning! JSLint will hurt your feelings!
JSLint.VS2010
18
DEMO
JSLint
19
Ajax
jQuery:
$.ajax, $.load, $.post, $.get, $.getJSON, $.getScript
ASP.NET:
WebForms: PageMethod, WebMethod
MVC: Controller, ApiController (Web API)
20
Ajax issues
• Exception from the server
• Expired session
• Expired authentication cookie
• Redirects
• Browser connection limits
Our practice: wrappers on both ends
21
DEMO
Bullet-proof Ajax
22
HTML rendering on the client
• jQuery Templates beta, jQuery Data Link beta
• JsRender pre-beta, JsViews pre-beta
• KnockoutJs
JSON  HTML
I want my data-binding!
23
DEMO
Data-binding on the client
27
Fixing bugs
Are you creating bugs too? Or, it’s just me…?
Debug Trace Log
alert
console
log4javascript
HTML5 localStorage
28
DEMO
Logging on the client
29
Summary
You are a Windows developer too!
30
Thank you!
Questions?
György Balássy
balassy@aut.bme.hu
http://gyorgybalassy.wordpress.com
@gyorgybalassy
Zoltán Dávid
david.zoltan@aut.bme.hu
Download slides and demos: http://bit.ly/msbg2012
Don’t forget to submit
your feedback and win a
great Nokia smartphone
and Kindle e-reader!

That’s not your var – JavaScript best practices for C# developers

Editor's Notes

  • #8 The first question when you want to use a feature is whether the user’s browser support it? The classic way to answer this question is to query the browser’s name and version and lookup the feature in a compatibility matrix. The problem with this user agent sniffing approach is, that it’s not future-proof. Browsers are constantly developing, features that are missing today will be implemented, and bugs that exist today will be fixed by a service pack. The recommended approach is called feature detection. Instead of checking the browser and its version, check whether a given feature is available in the current browser. You absolutely don’t need to know what the current browser is, all you need is whether a feature is available or not. For example the games in our game site rely on HTML5 canvas. If canvas is not supported in your browser, you can’t play these games. The Bring It Down game displays a friendly error message when you try to play with it in IE7. But you can have more granular control. If HTML5 audio is not supported, games can be played but you won’t have sound effect and background music.
  • #9 Detecting features can quickly became complex and frustrating, because you have to test your detection logic in multiple browsers. And the logic itself can become complex too. For example if you want to be sure that a video file can be played natively, you should detect not only the support of the video tag, but also the video codec. Here’s a quick tip: If you go the diveintohtml5.info website, you can find tons of detection function that you can build into your code.
  • #10 But instead there’s a much better approach: use Modernizr – it’s the best open source library to detect features. It’s very simple: just include it into your page, and after it loads you can query it’s Boolean properties to know whether a certain feature is supported or not. You want to use web workers? Just check if the Modernizr.webworkers property is true. You can also use Modernizr in CSS. When Modernizr loads, it adds CSS classes to the root html element of your page. For example, when the current browser supports box shadow, it adds a CSS class named „boxshadow” to the root html element. When box shadow is not supported, the name of the class will be „no-boxshadow”. Using this you can write CSS selectors that show or hide parts of the page, or format a DOM element with a CSS3 technique or use a classic solution. --- jQuery: $.support is primarily intented for jQuery’s internal use, and specific properties may be removed when they are no longer needed internally to improve page startup performance.
  • #21 We faced some really nasty issues while we were using Ajax. First, what happens when your server side endpoint throws an exception? In WebForms it’s not a problem, you can catch it with the Application_Error event handler in Global.asax. However this event handler is not called when an Ajax error occurs. It’s not obvious how you can implement a centralized error handler for Ajax. There can be problems too, when you have sessions. Your user can load a page, let it just be there in the browser and can trigger an Ajax request only after the session has been expired on the server. The Session module will start a new session without any further notice – and you should prepare your code for it. A very similar scenario can happen when the authentication cookie expires. But in this case the FormsAuthenticationModule will transparently redirect to the Login page. In fact the server will return a HTTP 302 Redirect to the client, and the client will do what the HTTP standard mandates: it will follow the redirect without any notice and will download the Login page. In the end your success callback will be called, because the Login page returned with HTTP 200 OK, and you will receive the HTML markup of your Login page. Issues can arise with the browser connection limit too. Browsers limit the number of simultaneous connections to the same server, and if your page allows your user to trigger Ajax requests quicker than the server can process them, then you can max out this limit. We found, that when it happens, different browsers behave differently: some loses requests, some loses responses. These are all very nasty bugs, that are very hard to detect especially on the developer’s machine. We found that they can be correctly fixed only if you think of them in advance. Our practice is to use wrappers on both ends of the connection.
  • #22 On the server here we have an Ajax endpoint. It’s a WebMethod in an ASP.NET webpage, with quite simple signature: it expects a string and returns a string. Let’s see what happens when an exception is raised within this method. In Fiddler here we have the response and you can see the full stack trace returned to the client with a HTTP 500 return code. Here’s how we do it. We created two simple classes. AjaxResult is a generic class that will always be returned for success and also for errors. It contains the original return value and any additional values that you want to return. For example it can contain a result code or an enum. The question is how to transform the original return value to our new AjaxResult in the simplest way. We found the lambda syntax for most readable. This AjaxResult.Execute method runs the code within its body and converts the result of this code block to AjaxResult. An additional advantage of this pattern is that now we have a centralized location for initializing and finishing Ajax calls. On the client we also have a wrapper we use instead of directly calling $.ajax. Here we have the standard success and error callbacks. Because all server side errors are caught on the server, you can use any returned property to detect whether the call was successful or failed on the server. For example here we use the returned Success property. In case of success we simply call the success callback, and we also unwrap the returned value from the d property, that is created by the ASP.NET runtime, even if you don’t need it. The classic error callback is used for low level errors. For example if the authentication cookie expired, the server can return a HTTP 401 and here you can redirect the user to the login page.
  • #23 Ok, so now you have the data on the client and you want to display it. On the server it is very easy, just use the well-known data-binding for rendering. On the client, however, it’s different and the classic approach is to use string concatenation to do it. Well, you can guess, that the result is horrible, and absolutely unmaintainable. Fortunately there are JavaScript libraries that allow templating on the client. In the last years Microsoft started promoting these libraries too. The problem is, that they have chosen a different library in about every year. They started with the late Microsoft Ajax Library, then created the jQuery Templates and the Data Link plugins. These are very good plugins, works quite well and we use them in our projects even they are in beta. Earlier there were announcements about merging them into the jQuery core, but in fact that will never happen. They are in beta and they will remain in beta. The author if these plugins, Boris Moore is started to work on two other libraries, JsRender and JsViews. These two are in pre-beta currently and hopefully a beta will be released in Spring, and sooner or later they will replace the Templates and the Data Link plugins. But you can also find other very good libraries to do data-binding on the client. For example KnockoutJs is a very good and respected library. What’s more it’s not in beta or pre-beta, it’s in version 2! --- From Boris Moore’s blog (http://www.borismoore.com/2011/10/jquery-templates-and-jsviews-roadmap.html): jQuery templates: Will remain at Beta1, and be superseded by JsRender templates, and JsViews. JsRender: Soon move to Beta – then on to V1 jQueryUI plan to use JsRender. (TBD whether it will migrate to jQuery project in GitHub...) JsViews: Move to Beta (after JsRender) and then on to V1 … May also be used by jQueryUI "In fact my advice to folks already using tmpl is to wait for JsRender Beta, and think of porting at that time… If not yet using tmpl, then by all means start with JsRender, but bear in mind the likelihood of upcoming changes"   In the meantime I am working as quickly as I am able to (compatible with my team commitments at MS) towards bringing JsRender to Beta, with a stable API and template syntax. My current expectation is end of February (but that is not a formal commitment from my team). JsViews Beta will probably be around April…
  • #25 The technique used by Knockout to hide additional data in the DOM is called HTML5 custom data attributes. Actually it’s my favorite part of the HTML5 set. It’s very simple: if you want to add any data to a DOM element, create a new attribute for it, but make sure you add the „data-” prefix to the attribute. That’s it. Because this attribute is not in the HTML5 spec, browsers – even old browsers – will ignore it. The fun part is, that you have full JavaScript support to get and set this value in jQuery. This approach is much more flexible and much more lightweight than hidden fields. Please forget hidden fields when you want to hide some data in the DOM. Not an accident, that unobtrusive validation in MVC – which we use on the game site – relies on custom data attributes.
  • #26 Managing complex data values with jQuery and FireQuery. Unobtrusive JS.
  • #27 Hidden fields are too heavy.
  • #28 When you create a bunch of code you also create a bunch of bugs. The debugging tools in Visual Studio and in the browsers are quite good. Actually they are much better than you would expect, if you hadn’t checked them before. But what if you want to do tracing or logging? The first way everybody tries is using alert. The JavaScript alert function displays a message box in the browser and you can display any string in it. The problem with alert is that it is a modal dialog, thus it hijacks the focus, the thread and can trigger new keyboard or mouse events. Don’t misunderstand me: alert is good many times, just please be aware of its drawbacks. Another common approach is using the console object that is available in most modern browsers. It’s not supported by older browsers, but can be easily used to display a message you need for tracing. However it is useful only in development time, because it is not persistent and you cannot collect the logs from your user’s machines. Zoltán will show you two other techniques, that overcome even these limitations. --- http://blogs.msdn.com/b/cdndevs/archive/2011/05/26/console-log-say-goodbye-to-javascript-alerts-for-debugging.aspx alert: hijacks focus, thread, triggers new events console: powerful but needs wrapper code, because it is not supported by every browser. Hard to turn off for production. http://blogs.msdn.com/b/cdndevs/archive/2011/05/26/console-log-say-goodbye-to-javascript-alerts-for-debugging.aspx log4javascript:
  • #30 These are our practices, the most common techniques we use when we create web applications. The fun part is, that the stuff we showed you today, HTML5, object-oriented JavaScript, Ajax, templating, custom data attributes – all of them can be used when you create desktop applications for Windows 8. In Windows 8 you have the option to use HTML and JavaScript to create Metro-style applications. So if learn these tricks, you are not only a web developer any more, but you are also a Windows developer.