Writing Apps Part I: WINJS, Web Apps and JQuery

April 4, 2014

Blog | Technology | Writing Apps Part I: WINJS, Web Apps and JQuery
Writing Apps Part I: WINJS, Web Apps and JQuery

Lost in Translation: WinJS is a New Country With the Same Language.

I recently wrote a Windows 8.1 tablet app for my company, Geekhive.  I learned a lot about the framework, async programming, and even (at my jaded old age) JavaScript.  This is the first in a multi-part series about my learning experiences with WinJS and its strengths and weaknesses.

In the latest release of Windows, MS released WinJS- a development framework that is meant to draw web developers back into the “native app” fold.  It allows programmers to write desktop or tablet apps in plain-old HTML and JavaScript.  This seems like a win-win for everyone.  See, in order for the whole Windows App Store model to work, MS needs a lot of programmers churning out apps for its ecosystem.  Many of those programmers are out on the web, where the technology is new and exciting, the visibility great, and the community mature.  So WinJS is an attempt to get some of that energy back into the MS desktop development arena, with the flip side that it lets web developers target the desktop/tablet with their core skills.

In Theory.

Jquery doesn’t work.  Let that sink in a bit.

Jquery is one of the most popular and widely-used javascript frameworks on the web.  Most any web developer worth his or her salt will know Jquery like a trusted friend.  It’s like a carpenter’s hammer: not right for every problem, but oh-so-right when the problem is a nail.  Let’s face it, in web development there are a lot of nails to pound.  So not supporting jquery out of the box presents a road block, an accessibility problem.

Let’s backup and look at why and how to work around the problem.  A WinJS application is really just a sandboxed Internet Explorer browser, running as its own full-screen app.  For obvious reasons, MS tightened down the security: shoddy JavaScript running in a browser application is one thing, but shoddy JavaScript running as a browser application is another.  The most obvious tightening they did was for DOM manipulation.  In particular, Jquery wants to append, prepend, and manipulate the DOM in ways that MS considers unsafe.

There are work-arounds though.  According to what I readJquery 2 is supposed to run in WinJS with no problems, but I never experienced that success.  Instead, I used a work-around that MS built into their security model: the ‘MSApp.execUnsafeLocalFunction” method.


I modified my local copy of Jquery to wrap every “appendChild,” “insertBefore,” etc, call with the unsafe wrapper.  In all, there were 8 locations.  Let’s be clear here though: I don’t recommend hacking the standard libraries like Jquery on a production application.  It incurs a lot of risk.  However, it seems I’m not the only person who arrived at this solution.  We also implemented the Telerik charting library in the app: low and behold they implement their own modified version of Jquery, with all the appends, and inserts wrapped in “MSApp.execUnsafeLocalFunction” goodness.

After that, Jquery worked like a champ.  Unfortunately, other libraries that do similar things will encounter the same pain.  In particular, Angular.js, but we’ll get to that in another post.

To be fair, MS implemented their own patterns for developing apps in WinJS, but that’s completely beside the point: if you want web developers to use your stuff, let them use it their way.

It’s not a Web App.

The next major stumbling block has to do with architecture.  From 10,000 feet up, it sounds a little silly to say “Web applications are different from desktop applications.”  But when the desktop app is written in HTML and JavaScript, it’s harder to make that clear of a distinction.

MS went to great pains to make Javascript interoperable with C# and C through the WinRT framework.  The temptation here is to sketch out your desktop application’s architecture so it looks like the architecture of a web app.  After all, JS can handle the UI, and C# can handle the heavy lifting of data access, file IO, etc.  There are two problems here.  First, a web app communicates with the server over http, and most JS libraries put forth a well-understood use-pattern for this communication.  WinJS doesn’t follow this pattern, and there isn’t a large body of knowledge on how best to do this stuff.  Second, when you return some data from a WinRT component, it’s not plain-vanilla JavaScript, it’s a reference to a WinRT object.  These two facts have huge repercussion when it comes to productivity and application design.

Another paradigm shift is availability of resources.  In particular, JavaScript has access to the entire WinRT framework, so it can read and write from disk or even launch applications.  That’s a big change.  But in the same breath, C# and the other .Net languages only have access to the WinRT framework, not the full .Net framework.  This is a bit of a culture shock, as it forces new patterns onto both JavaScript and C# developers.

I Promise.

promises library to let them play nice with JavaScript.  This is a good thing, as apps that fully embrace an async mindset will feel faster and more responsive to the user.

C# code that returns some value to JavaScript will execute asynchronously and return at some undetermined point in the future.  You can’t stop the train and make JS wait for a result, and you don’t want to.  Instead, you can tell it how to respond when the result is returned.  That’s where promises come in.  Roughly speaking, JavaScript promises are designed to trigger a callback when the promise is completed, usually with the “then()” function.

In this case, the C# object has returned some data, and it is passed to the callback as a single param: “settings.”  You don’t need to do anything to implement the promises library on the return, MS has done that for you.  It’s a very elegant decision, and in line with what is happening in modern JavaScript design patterns.

There are a couple of problems though.  Implementing promises and forcing async programming are good decisions, but how its enforced leaves a little bit to be desired.  On the C# side, it enforces an abstraction/wrapper pattern that seems a little “kludgey.”

There are two functions in this graphic: the first exposes the second as an IAsyncOperation of type “Settings.”  The “Settings” object is merely a C# class with a few properties.  The problem is that WinRT cannot expose Settings, a Task, or even an async method.  You have to wrap it in another method call that casts it to an exposable WinRT type.  Any time you wish to return data from disk, or use any other method that is async, you are forced into this pattern.  In order to consume the WinRT async method, you must invoke the “await” keyword, which requires that the containing method be marked async, which requires that it return a Task, not Settings, and on and on.  This isn’t an expensive pattern if used lightly, but it is not well-documented, and it starts to bloat the code if you perform regular disk IO.

Because WinRT gives JavaScript some super powers, and apparently hobbles C#, it is probably a better architectural decision to let JS do more heavy lifting, and push C# off to the back-burner.  After all, they both talk to the same framework, and making the two talk to each other requires a lot of extraneous code.  Be forewarned though: beefing up JavaScript’s role in the application requires that you implement some sort of code-organization strategy, and a robust one.  MS provides a way to use “Namespaces” in JavaScript, and there are a number of other patterns, like MVC, the module pattern, etc.  That discussion is for another day, but know that you’ll need to deal with it and have a plan.

A Burning Bridge Over Trouble Water.

And that brings us back to a recurring point: MS has provided a great set of tools, but they aren’t the tools that programmers are using elsewhere, and they probably aren’t portable to the web.  Web developers are probably not going to write a WinJS app in the MS style (MS namespaces, no Jquery,etc) and port it to the web.  One might write a WinJS app with Jquery and port it to the web, but it’s painful.  So why build a bridge between desktop and web development if it’s already on fire?

I think the short answer to that nearly-hypothetical question is that this is version 1.0.  MS usually gets things right in time, and this is brand new stuff.  Besides, software is (and always has been) a moving target.  In a year WinJS might be significantly less painful, or it might be deprecated.  And we might be talking about some brand new type of device that is neither a web browser, a desktop, a tablet, or even a phone.  the technology is changing so fast, and it seems that only the web has been able to keep pace with devices.

Tune in next time as I talk about developing a WinJS application using Angular.js.

Dan Clouse

Senior Developer
Tags
  • Apps
  • Async
  • JavaScript
  • Jquery
  • Windows 8
  • WinJS

Recent Work

Check out what else we've been working on