Wednesday, March 30, 2016

Windows 10 Universal JavaScript Debugging TypeScript

Overall, still loving the new Windows 10 Universal Platform JavaScript apps.  Feels just like building for the web.  The one big difference I'm noticing now is that debugging is actually easier in web pages.  How is this possible?

In the browser, when things go wrong, you hit F12 and you're off to the races.  Right click, inspect anything on the page, execute scripts in the console, hover over scripts (including TypeScript) and see the property value, etc.  All good stuff, especially the fact that I can debug my typescript files.  I do not need to work with the generated javascript and figure out what that was in the typescript.

In universal apps, it's closer to traditional development with visual studio where you can set breakpoints and view watch window or locals.  I will say that breakpoints work better in studio than in the browser generally as you can more easily set breakpoints on inline lambda functions that I have not figured out how to do in the browser.

Eg,

this.controller.fetchData().then((result) => [breakpoint] this.storeResult(result));

Breaking into the lambda as written here is difficult in the browser, I would normally have to convert the statement to:

this.controller.fetchData().then((result) => {
    [breakpoint] return this.storeResult(result);
});

so that the function body has a line number which to set the break.

However, the horrible downside to the windows universal stuff is that in the debugger, if you are working on typescript, it will tell you everything is undefined.  Why?  Because of JavaScript's scoping for the this keyword.  In the generated code, you'll find _this is the reference you'll need to work with the object in the console.

Also, I cannot find anyway to 'inspect' the output in the simulator so that finding elements in the page to modify is definitely more difficult.  You do get all the nice features of being able to edit style sheets or markup, but when you modify TypeScript files, it doesn't actually use the modifications!  This can be terribly confusing as the debugger will walk the script with the change, but just not use the modified code.  This may not be true if you directly modify the javascript (haven't tried), but you definitely have to restart the app for type script changes to take hold; which honestly is OK since the TS is compiled during the build, however, it should not give the appearance of being modified and running the modified code.  Simply disallow it or give some grayed out indicator that the code is not actually being used.

Hopefully the 'this' scoping will be fixed soon and a way to inspect would make the development experience better than web development.

Thursday, March 24, 2016

Windows 10 Universal JS with Application Insights

Man oh man oh man.  So much confusion around what is possible with Windows 10 Universal JS apps.  If you google around for what you can and cannot do or how to do things, you'll likely find references to Windows Phone 8 vs 8.1 and silver light and all kinds of stuff so I'm trying to track down what actually works and the proper way of including things in these new projects.

There are even articles that say you cannot do certain things in JS applications or that they are different than the XAML versions, but often no reference is even given to the JS applications.  Store Apps only have XAML references and often JavaScript is referred to as 'JavaScript Web Pages' which is even more confusing.

As of this article's writing, however, the following seems to be true about application insights with regards to Windows 10 Universal JavaScript Apps.

Yes, you can absolutely use Application Insights!

But how?

Normally, when creating a project, you'll have an option to automatically add application insights to your project.  However, this is not the case with Universal JavaScript Applications.  You simply get a blank slate with nothing really provided for you.

You will need to get a special version of the AI library, which can be found here on github.  There is also a minified version available in this repo.

Include this in your js folder, and add it to whatever page/s you want to track by adding a script reference in your HEAD section.

Go to the azure portal and create a new Application Insights Developer Service or locate the instrumentation key for an existing instance.

Then, in your app start code, initialize a new AppInsights object with your instrumentation key and specify the enpointUrl as 'http://dc.services.visualstudio.com/v2/track'.

// For an introduction to the Blank template, see the following documentation:
// http://go.microsoft.com/fwlink/?LinkId=232509
(function () {
 "use strict";

 var app = WinJS.Application;
 var activation = Windows.ApplicationModel.Activation;

 window.appInsights = window.appInsights || new Microsoft.ApplicationInsights.AppInsights({ instrumentationKey: '', endpointUrl: 'http://dc.services.visualstudio.com/v2/track' });
 window.appInsights.trackPageView();

 app.onactivated = function (args) {
  if (args.detail.kind === activation.ActivationKind.launch) {
   if (args.detail.previousExecutionState !== activation.ApplicationExecutionState.terminated) {
    // TODO: This application has been newly launched. Initialize your application here.
   } else {
    // TODO: This application was suspended and then terminated.
    // To create a smooth user experience, restore application state here so that it looks like the app never stopped running.
   }
   args.setPromise(WinJS.UI.processAll().then(function () {
    // for debugging, keep global reference
    window.applicationViewModel = new ApplicationViewModel();
       ko.applyBindings(window.applicationViewModel);
   }));
  }
 };

 app.oncheckpoint = function (args) {
  // TODO: This application is about to be suspended. Save any state that needs to persist across suspensions here.
  // You might use the WinJS.Application.sessionState object, which is automatically saved and restored across suspension.
  // If you need to complete an asynchronous operation before your application is suspended, call args.setPromise().
 };

 app.start();
})();

That's all there is to it!  You can now view page requests, dependencies, ... in the portal.  It seems that the Visual Studio integration does not work with this approach (at least not with the simulator) so you will not receive notifications or trace data in studio while running in the simulator.

Monday, March 21, 2016

Windows 10 Universal JS + Typescript

While investigating the Windows 10 universal javascript application story, I have been trying to use all the good things that I normally use when developing web applications.  As such, I would like to use TypeScript to help generate valid, working javascript.  Using Typescript is no problem for universal applications as the files are compiled into javascript and available at runtime.

The not-so-obvious part, however, is that by default, no Windows 10 Universal specific definitions are included or available for use by newly created projects.  When working with Web Applications and Windows Universal 10 JS applications, lib.d.ts is available when writing TypeScript files so that things like window.localStorage are available.

When working with universal apps, however, we do not want to use window.localStorage, but instead Windows.Storage.ApplicationData.current.localStorage should be used.  By default, however, this is not available to typescript files.  You must install the definition from nuget or elsewhere.

PM> Install-Package winjs.typescript.definitelytyped
PM> Install-Package winrt.typescript.definitelytyped

These packages will provide definitions for storage and other native APIs that can be called from javascript.

Hopefully this will save someone else hours of searching! :)

Thursday, March 17, 2016

Windows Universal 10 JavaScript App + Knockout.js

I finally decided to see what the universal app stuff is all about, and was ready to finally tackle XAML when, to my surprise, I found that you can write your app using JavaScript and HTML.  No thanks to the template being buried out of the way.  I figured it would have been an option once I picked Universal App just like when you create a Web App you can select WebApi, MVC, Web Forms, how accounts will be handled, ...  Thank god for channel 9.

Even though I found that I *could* do a JavaScript universal app, I figured it would be some really limited subset or quirky, but so far, it's been pretty much an outstanding process.  I was unsure what would and wouldn't work, so I decided to just throw everything I wanted into the project and see what worked.  So far, everything has worked!

In preparation for the project, I googled around about including Knockout.js into a Windows Universal 10 JS App and did not find my information.  In fact, the information that I did find turned out to not work.

I was able to use the package manager to install all of the following:

PM> Install-Package Knockoutjs
PM> Install-Package knockout.TypeScript.DefinitelyTyped
PM> Install-Package fontawesome
PM> Install-Package jquery
PM> Install-Package jquery.typescript.definitelytyped

Honestly, I feel dirty including jquery as I really only ever use the ajax and promises parts of it and should probably learn a better way of dealing with those concerns.  More on that another day.

In default.html, include knockout before the default.js file so that it is in scope when default.js runs.  Modify default.js to include a call to ko.applyBindings.

default.js:
    // For an introduction to the Blank template, see the following documentation:
    // http://go.microsoft.com/fwlink/?LinkId=232509
    (function () {
 "use strict";

 var app = WinJS.Application;
 var activation = Windows.ApplicationModel.Activation;

 app.onactivated = function (args) {
  if (args.detail.kind === activation.ActivationKind.launch) {
   if (args.detail.previousExecutionState !== activation.ApplicationExecutionState.terminated) {
    // TODO: This application has been newly launched. Initialize your application here.
   } else {
    // TODO: This application was suspended and then terminated.
    // To create a smooth user experience, restore application state here so that it looks like the app never stopped running.
   }

   args.setPromise(WinJS.UI.processAll().then(function () {
       ko.applyBindings(new ApplicationViewModel());
   }));

  }
 };

 app.oncheckpoint = function (args) {
  // TODO: This application is about to be suspended. Save any state that needs to persist across suspensions here.
  // You might use the WinJS.Application.sessionState object, which is automatically saved and restored across suspension.
  // If you need to complete an asynchronous operation before your application is suspended, call args.setPromise().
 };

 app.start();
})();



In this example I have a new ApplicationViewModel that is being created and bound.  The script file containing the view model also needs to be included on the default.html page.

It's just that simple.

So far, the only things that's really different about this compared to MVC is there is not a routing engine and razor (that I've come across at least).  Just simple page using relational links as you might do in a simple website.

At any rate, I highly encourage anyone that is a web developer to take a look at the Windows Universal 10 JS Apps.