Updating a Windows 8 JavaScript app from RC to RTM

Now that the Windows 8 RTM version is available to MSDN Subscribers (and a 90-day trial version is available for non-subscribers), it’s a good time to update your app to the RTM version of Visual Studio 2012. Updating to RTM is required to submit an app for the Windows Store, and it’s a pretty painless process.

Updating WinJS

One significant change between apps built with the Visual Studio 2012 release candidate and those built with RTM is the version of the Windows Library for JavaScript (WinJS) used. WinJS has been updated for RTM, so if you’re migrating an app from RC to RTM, you’ll need to update WinJS. There are two parts to this process:

Continue reading Updating a Windows 8 JavaScript app from RC to RTM

Follow-up On Backups: Mounting a System Image

Yesterday, I posted about my practice of using the built in system image creation tools in Windows 7 and Windows 8 to create a backup of my system whenever I’m getting ready to upgrade.

Now, if something goes tragically wrong, I can just boot to a system repair disk, and restore the image, and I’m back to where I started. But let’s suppose the install goes fine, but I find that there’s a file I need to get to from my backup, but I don’t want to restore the entire backup, just get that file.

Continue reading Follow-up On Backups: Mounting a System Image

Preparing for Windows 8 RTM with a System Image backup

Getting RTM Bits

You’ve probably heard by now that for folks who are MSDN Subscribers, the RTM version(s) of Windows 8 and Visual Studio 2012 were made available for download today.

Even better, for folks who aren’t subscribers, you can grab a 90-day trial version from TechNet (do make sure to read the “Things to Know Before You Start” section for important considerations).

And you can get a bunch of developer downloads for building Windows 8 apps from the Windows 8 Developer Download page, including Design assets, sample apps, Visual Studio 2012 Express and more.

Continue reading Preparing for Windows 8 RTM with a System Image backup

W8WIL #3: Timers using setTimeout in a Windows 8 app

In this, the third, post in my series “Windows 8: What I’ve learned,” I’ll share how the behavior of script loading and unloading in some Windows 8 Metro app templates require a different approach to using setTimeout for timers.

Background

RPAHome_2 I recently had the opportunity to spend some more quality time with the Visual Studio 2012 release candidate, building a Windows 8 app for some of my teammates who focus on Windows Azure, Brian Hitney, Peter Laudati, and Jim O’Neil. You can see a screenshot of the app to the left.

One of the really cool things that these guys have built on top of Windows Azure is the Rock Paper Azure Challenge, an contest to see who can code the most effective online bot to play the game Rock, Paper, Scissors in the cloud. Cool prizes are available, from Best Buy gift cards, to Windows Phones to XBOXes and Kinects.

For TechEd North America this week, they came up with a very special contest, called Beat The Gu. The idea is simple…Scott Guthrie (whom most of you probably know now runs the Azure team), has a RockPaperAzure bot, and TechEd attendees could compete to see who could beat his bot (with a top prize of a 60″ LCD TV).

One of the features that the Rock Paper Azure Challenge provides is a set of leaderboards for all of the various contests that are currently running, with the data accessible via the OData protocol. This makes it super-simple to grab the data in a Windows 8 Metro style app as either XML (ATOM-Pub format) or JSON. I chose to build the app using HTML and JavaScript, so JSON format was perfect.

I’ll be sharing more details on the app and what went into it in a future post, but for now I want to focus on one of the things that bit me during the development process, namely using setTimeout to create a timer.

What I Learned

For the Rock Paper Azure Leaderboard app, I used the Navigation app template, which consists of a default.html page containing a div that becomes an instance of the PageControlNavigator class, which is defined in a script file called navigation.js. Basically this control provides an easy way to dynamically load fragments of markup, CSS and script referred to as Page controls at runtime. And the way that script resources are loaded and unloaded is a little different when using this template, as we’ll see in a bit. You can read more about how single-page navigation works here.

One of the most important features was for the leaderboard information on the home page to be refreshed periodically, since the contest takes place in rounds and after each round, the position of the players will typically change. Since I was using HTML and JavaScript to build the app, the natural way of doing this was to use JavaScript’s setTimeout function to periodically refresh the data.

In earlier versions of the app, I had code in the home page’s ready function that would call a function in my data.js file (modeled after the pattern in the Grid app template) to retrieve a WinJS.Binding.List with the leaderboard data, then bind that data to a ListView on the page. Once all that was done, I would call setTimeout, passing it the name of the function to refresh the data, along with the timeout duration, something like this:

   1:  ready: function (element, options) {
   2:      var promise = Data.init();
   3:      promise.done(
   4:          function (leaderboardList) {
   5:              leaderListView.winControl.itemDataSource = leaderboardList.dataSource;
   6:              setTimeout(dataUpdateLoop, 30000);
   7:          }
   8:      );
   9:  }

Essentially, the code above will call a function named dataUpdateLoop after 30 seconds. This works great…as long as you stay on the home page.

RPA_scripts_2Although Windows 8 apps written in HTML and JavaScript use standards-based technologies, there are some subtle differences in how the JavaScript and CSS files are loaded (and unloaded, importantly) when using the Navigation app template. With a web site, when you switch to a different page, the DOM is unloaded, and any scripts that were running are no longer in scope. The new page is then loaded, along with any scripts it references.

In an app based on the Navigation template, script loading is a little different. When I run the app, all of the scripts and such required to display the homepage are loaded, as shown in the Solution Explorer screen capture to the left. The base.js and ui.js files are part of the WinJS library, and will always be loaded in a Metro style app (they’re referenced in default.html). default.js and navigator.js are loaded by default.html, and provide support functionality for the entire app, since default.html acts as a parent container for the whole app. settingsUtil.js and searchResults.js are also loaded by default.html, and support the Settings pane and Search contract, respectively.

The remaining JavaScript files, data.js, home.js, and converters.js, are loaded by home.html, which is a Page control that is loaded automatically when the app starts up. Now let’s take a look at what happens when we go to a different part of the application, for example, we can visit the player details page by tapping or clicking on one of the player tiles on the leaderboard:

RPA_playerDetails_4 When the details page loads, we see the screen to the right, which shows us the details for the selected player, including their current place, number of wins and losses and ties, total points, and the date and time of their last match. But of greater interest is what happens with our scripts. If we take another look at the Solution Explorer, we’ll see that another script has been loaded, playerDetails.js, as shown below:

RPA_scripts2_4

In addition to the new JavaScript file being loaded, notice what didn’t happen…none of the previously loaded scripts were unloaded. BUT…the controls on the homepage (most critically the ListView control containing the leaderboard info) are no longer instantiated. The impact of this, as I discovered in testing the application, is that the timer I set in the code above continues executing, but because leaderListView is no longer instantiated, the dataUpdateLoop function will throw an exception.

Suffice it to say, this was not an acceptable result. I still needed to update the leaderboard on a regular basis, but having the app throw exceptions or crash if I tried to look at the details or use other functionality in the app was not OK.


The Solution

I’m sure there are probably any number of ways to work around a problem like this, but here’s what I came up with (I welcome suggestions for a more elegant or robust solution in the comments). The key is to clear the timer when you move to a different page, and restart the timer when you come back to the home page. Conveniently, JavaScript includes a function for just this purpose, called clearTimeout (there’s a corresponding version for setInterval as well if you’re doing timers that way). But you need to do a little more work in order to use it. clearTimeout requires you to provide it with the ID of the timer you want to clear, which conveniently is a return value of the setTimeout function when called (in my code above, I was simply ignoring this value).

To implement this, I refactored my code as follows:

   1:  ready: function (element, options) {
   2:      var promise = Data.init();
   3:      promise.done(
   4:          function (leaderboardList) {
   5:              leaderListView.winControl.itemDataSource = leaderboardList.dataSource;
   6:              if (appSettings.refreshData()) {
   7:                  appdata.current.localSettings.values["currentTimeoutId"] = 
   8:                      setTimeout(dataUpdateLoop, appSettings.refreshDataInterval());
   9:              }
  10:          }
  11:      );
  12:  }

In the bold section of the code above, I’m capturing the ID of the timer that I’m creating with setTimeout, and storing it as value named “currentTimeoutId” in my local settings. That allows me to access the ID later if I need to clear the timer. I’ve also modified the code to include a check of another setting, refreshData, which is defined in settingsUtil.js, and is a boolean value indicating whether or not to perform the refresh. I’ve also moved the refresh interval into a setting which is likewise exposed by settingsUtil.js. To cancel the timer when navigating to another page, I simply add the following code to the function that’s mapped to the ListView’s oniteminvoked event:

   1:  function itemInvoked(args) {
   2:      args.detail.itemPromise.done(
   3:          function (item) {
   4:              if (appdata.current.localSettings.values["currentTimeoutId"]) {
   5:                  clearTimeout(appdata.current.localSettings.values["currentTimeoutId"]);
   6:              }
   7:              WinJS.Navigation.navigate("/pages/details/playerDetails.html", item.data);
   8:          }
   9:      );
  10:  }

In the bold section of the code above, I’m testing whether I’ve captured an ID from a call to setTimeout, and if so, I’m calling clearTimeout and passing in the relevant timer ID. That’s all there is to it!

Summary

When using JavaScript to write an application, whether for the web, or for a Windows 8 app, you need to be careful to understand the scope in which your code is executing, as well as when that code is loaded and unloaded. The Windows 8 Metro app development environment helps you by including best practices, such as wrapping your page code inside a self-executing anonymous function, to help you avoid problems with variable name collisions, etc. The Navigation template is a great place to start because it provides some key infrastructure (including a consistent back button users can use to go back to the previous page) to help you help your users find their way around your app. But you need to keep in mind that script loading in a Metro style app behaves somewhat differently when using the Navigation template to implement single-page navigation.

Note that this tip also applies to the Grid App and Split App templates, since they use the same single-page navigation pattern using navigator.js.

I hope you found this tip useful…if so, please share with your friends and colleagues!

W8WIL #2: Declaratively Specifying an ItemTemplate in a Fragment

I’ve been playing quite a bit over the last few days with the new Windows 8 Release Preview, as part of a special team project I’m working on with some of my fellow DEs. One of the areas I was working on is doing some simple databinding using a ListView control in a JavaScript Metro style app based on the Navigation App template. In this second installment of my Windows 8, What I’ve Learned series, I’ll give you a tip that may help save you some pain and troubleshooting time when declaratively associating an ItemTemplate for a ListView control inside a page fragment.

I was able to very easily create an array with a couple of objects, each with a couple of properties, and then bind those to the ListView by passing the array to the constructor of the WinJS.Binding.List object, which gave me a List object with a dataSource property that I could assign to the ListView’s itemDataSource property in the ready() function of home.js, like so:

listView.winControl.itemDataSource = myList.dataSource;

So far, so good…when I ran the project, the data showed up, in JavaScript object style, as expected. But since that’s not a very interesting way to display data, I of course needed to add an ItemTemplate, similar to the following:

   1:  <div id="myTemplate" data-win-control="WinJS.Binding.Template">
   2:     <div>
   3:        <div class="win-type-large myTitle" data-win-bind="textContent: title">
   4:     </div>
   5:  </div>

Once I had my template declared (note the data-win-control attribute that tells WinJS to instantiate this as a BindingTemplate), I had to tell my ListView about it, which I could do either programmatically or declaratively.

TIP: If you look at either the Grid App or Split App JavaScript templates, both show examples of assigning a template to a ListView programmatically.

I find declarative syntax a bit simpler, so I wanted to do it that way. In previous demos I’ve done, the syntax looked like this:

<div id="listView" data-win-control="WinJS.UI.ListView" 
   data-win-options="{itemTemplate : myTemplate}"></div>

I dutifully added the data-win-options attribute to my ListView markup, ran the project again, and…nothing. The underlying data was still being rendered as a JavaScript object.

I spent a couple of hours pulling my hair and making little changes to the code before it finally dawned on me to check the ListView quickstart documentation, and lo and behold, it turns out that the declarative syntax above doesn’t work when your markup is part of a page fragment, which is what you get as part of the Navigation App template. Instead, you need to use the following syntax:

<div id="listView" data-win-control="WinJS.UI.ListView" 
   data-win-options="{itemTemplate : select('#myTemplate')}"></div>

The “select” will walk the DOM to resolve the reference, while the direct id reference in the first example won’t work because the fragment markup hasn’t been added to the DOM by the time that the resolution takes place.

So if you’re working with ItemTemplates declaratively in page fragments, be sure to use the “select(‘#templateId’)” syntax to associate your template with your ListView.

(h/t Jeff Sanders – moderator in the Metro Style apps forums for more detail on the underlying issue)

Installing .NET Framework 3.5 in Windows 8 Consumer Preview (updated for RTM)

UPDATE:

Since the technique below was for the Windows 8 Consumer Preview, I wanted to share how you can accomplish this in the RTM release of Windows 8, from my reply to a commenter on the post:

For the RTM release, you can use “Turn Windows Features On or Off” in settings (just open the Search charm for settings (Win+W), and type “Turn Windows”, and you should see it at the top of the second column). Once you’ve got that dialog up, the first option available will be “.NET Framework 3.5 (includes .NET 2.0 and 3.0)”. Check the checkbox, click OK, and you should be all set.

Original post follows:

Continue reading Installing .NET Framework 3.5 in Windows 8 Consumer Preview (updated for RTM)

W8WIL #1: Friendly Names for AppBar Icons

Today, I’m kicking off a new blog series, which I’m calling Windows 8: What I’ve Learned, or W8WIL for short. I’ve had the good fortune of spending some quality time with the Windows 8 Consumer Preview release, and there are plenty of little things that can make your life easier as a developer, and I’ll share those in this series.

In this first installment, I want to share some coolness in working with AppBars in your JavaScript Windows Metro style apps. For those of you who haven’t yet started playing with the new app types (if you haven’t, you can grab both the Consumer Preview release, and the Visual Studio 11 beta bits here), the AppBar is a common location for commands for users to interact with content in your app. Below is an example of one of the neat apps that’s currently available in the beta Windows Store, called Physamajig:

Continue reading W8WIL #1: Friendly Names for AppBar Icons

Recipe for a Brittle Data Service

You can teach people a lot by writing about best practices.

But sometimes, you can also teach by illustrating your own boneheaded moves that tripped you up. In other words, don’t do what I did.

Case in point is a recent issue I ran into when attempting to demo some HTML5 and JS code at last week’s CMAP main meeting. I had built a simple HTML5 site for consuming event data and the twitter stream for Community Megaphone. The twitter feed was working fine, but the event data, which was being populated dynamically from the Community Megaphone WCF Data Service via a call to jQuery‘s .ajax function, wasn’t working at all.

Unfortunately, I discovered this only a few minutes before the start of the meeting. The site had worked fine the last time I demoed it, so I hadn’t felt a strong need to test it again. Oops!

While I was trying to troubleshoot before the meeting got started, I got as far as discovering that the data service was throwing a 500 error, but wasn’t able to dig in further until I had a bit more time the following day. Those of you who have worked with WCF Data Services are probably nodding your head in recognition. One of the choices that the data services team made to enhance security is to provide very little information when things go wrong. That’s great for security because one of the main ways that the bad guys figure out how to exploit systems is by attempting to make them fail, and gleaning information from error messages returned. Unfortunately, what’s great for security is lousy for troubleshooting, particularly if you don’t have immediate access to the source for the failing service.

The good news is that while WCF Data Services is tight-lipped by default, with a few simple tweaks, you can get it to open up about what’s causing the problem. Once I was back at my home office, sitting in front of the code for the service, here’s what I did to troubleshoot, per this post that’s been out for a while:

  1. Opened up the code-behind for the Data Service, and added the ServiceBehavior metadata attribute to the DataService class, with the IncludeExceptionDetailInFaults property set to True (note that you can also configure this via the <serviceDebug> configuration element in your behaviors in web.config):
    <System.ServiceModel.ServiceBehavior(IncludeExceptionDetailInFaults:=True)>
  2. As part of the InitializeService method, set the service to use verbose errors, which will provide additional detail on the error:
    config.UseVerboseErrors = True

Once you’ve made those changes (hopefully against a local or staging instance of your app, as you generally want to avoid sending detailed error messages in a production app), you should be able to see the full exception information, including the stack trace, and any inner exceptions. In my case, once I’d enabled these handy features, I saw the following when making a request to the service operation that was failing:

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<error xmlns="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata">
  <code></code>
  <message xml:lang="en-US">An error occurred while processing this request.</message>
  <innererror>
    <message>An error occurred while reading from the store provider's data reader. 
See the inner exception for details.</message> <type>System.Data.EntityCommandExecutionException</type> <stacktrace> at System.Data.Common.Internal.Materialization.Shaper`1.StoreRead()&#xD; at System.Data.Common.Internal.Materialization.Shaper`1.SimpleEnumerator.MoveNext()&#xD; [...]
at System.Data.Services.DataService`1.HandleRequest()</stacktrace> <internalexception> <message>Invalid length parameter passed to the SUBSTRING function.</message> <type>System.Data.SqlClient.SqlException</type> <stacktrace>
at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection)&#xD; at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection)&#xD; [...]
at System.Data.SqlClient.SqlDataReader.Read()&#xD; at System.Data.Common.Internal.Materialization.Shaper`1.StoreRead()</stacktrace> </internalexception> </innererror> </error>

I’ve omitted some of the stack trace info to keep it a bit more brief, but the key bit is the type of the outer exception (EntityCommandExecutionException) and the message of the inner exception (“Invalid length parameter passed to the SUBSTRING function.”). With this info in hand, I was able to track the issue down to the SQL Server Stored Procedure I wrote to handle queries for events within a given distance of either a latitude/longitude pair, or a zip code (which the data service converts to a lat/long on the fly).

Turns out that the issue was poor logic within the stored procedure. Because Community Megaphone supports both in-person and online events, I needed a way to return only those events which were within the given distance (calculated by a user-defined function), which required parsing the latitude and longitude of each event, which are stored as a single column in the db (whether that was wise is a discussion for another day). In the original sproc, I did this by checking whether the value of the State column was either blank or ‘NA’ (as in not applicable). This worked fine for a very long time, but apparently subsequent to writing the sproc, I must have made a modification to some other code that allowed events to be added with a value other than blank or ‘NA’, and as a result, there was an online event which appeared to the sproc to be an in-person event. And when it tried to parse the non-existent lat/long value, it threw the exception above.

Fixing the data error was easy enough once I knew the cause, but that would only fix the problem for that one event. Fixing the sproc was pretty simple, too. Since the data that I’m parsing is the latlong column, then I just needed to make sure that there was a value in that column before trying to parse it. In .NET code, you’d simply call String.IsNullOrEmpty(stringval), but T-SQL doesn’t have a native IsNullOrEmpty function, so what to do?

A quick Bing search, and the answer was found in this blog post, which shows how to add your own IsNullOrEmpty user-defined function:

CREATE FUNCTION dbo.IsNullOrEmpty(@text NVARCHAR(4000))
RETURNS BIT
AS
BEGIN
    IF ISNULL(@text, '') = ''
    BEGIN
        RETURN 1
    END
    
    RETURN 0
END

GO

If @text is an empty string, it will match ”, and return 1 (true), if it’s null, ISNULL will substitute ” for its value, and again, it will return 1. For any other value, the function will return 0 (false). With the UDF in place, my logic for parsing the latlong is more robust:

CASE
   WHEN dbo.IsNullOrEmpty(E.latlong) = 0 THEN LEFT(E.latlong, CHARINDEX(',', E.latlong) - 1)
   ELSE '0'
END,
CASE
   WHEN dbo.IsNullOrEmpty(E.latlong) = 0 THEN RIGHT(E.latlong, LEN(E.latlong) - CHARINDEX('-', E.latlong) + 1)
   ELSE '0'
END 

The above T-SQL, which is part of the query that returns the matching events, will only attempt to parse the latitude and longitude values if they exist. Otherwise, it will return ‘0’ for the values.

A couple of things to note:

  1. The error message I was receiving didn’t mention either LEFT or RIGHT, but rather SUBSTRING. That made it a little trickier to figure out what was going on, but thankfully, the sproc was only 32 lines long, so it wasn’t hard to suss out where the problem was. This is an excellent argument, IMO, for keeping your sprocs small and tight, and moving any logic that isn’t specific to the sproc itself into user-defined functions or other appropriate locations. As with methods in your classes, the fewer responsibilities a sproc has, the easier it’ll be to troubleshoot when it breaks.
  2. One thing I did not take advantage of in my stored procedure code (since remedied) is SQL Server’s support for TRY/CATCH blocks. By handling potential exceptions closest to their source, I can make my stored procedure (and hence my data service) more robust, and make it easier to determine what’s going on. I simply wrap the potentially problematic code with a BEGIN TRY / END TRY construct, and follow it up with a BEGIN CATCH / END CATCH. Inside the catch block, I can return my own custom error message, log the error, or handle it however I choose. In the case of this specific sproc, an exception will result in the service not returning any data, but that’s OK, as it will at least return, rather than hanging the ajax call.

Summary

So to wrap up, here are a few tips and points to remember when working with stored procedures and data services:

  • Keep in mind that by default, WCF Data Services does not return detailed exception information. This is a good thing, until you need to troubleshoot an exception…then you’ll want to remember config.UseVerboseErrors and IncludeExceptionDetailInFaults.
  • WCF Data Services exceptions will not be caught by ASP.NET’s Custom Error feature even if it’s enabled. As such, if you’re counting on Custom Errors to catch any problems you have in your code that don’t have specific exception handling written, you’ll be disappointed here. Make sure that your stored procedures (if used) and your data services code both have adequate exception handling in place, so that your service doesn’t fail completely when an exception arises.
  • Avoid inferring the existence of one column or value based on the value of another column…this was the root error on my part that led to my service crashing in the first place. While more robust exception handling would’ve mitigated the impact of the bug, testing for the value of the column I was actually trying to parse would’ve avoided the whole problem.
  • And a general tip for fellow speakers…ALWAYS check your demos BEFORE you get to the venue. Finding out about this problem even just a few hours earlier would likely have allowed me to fix it, rather than hack around it. I’ve been doing this long enough that I should know better, but clearly I needed a pointed reminder for why you don’t just assume that your demos that worked last week still work this week.

Hope you found this useful…if you did, please share this post with your friends!

Reuse in action: Bing Maps REST API and Community Megaphone

I am a fan of small changes that open up big opportunities. I’m also a fan of reuse, and leveraging code in multiple apps or scenarios. And those of you who’ve known or read my blog for any length of time also know that I’m fond of talking about Community Megaphone, which is my current case in point for reuse.

Overview

Over the past few weeks, I’ve been working on a project which will remain secret for now, but which will be revealed early next year. During the course of this project, I was doing some work with geolocation and mapping, specifically building a list of maps for items from the Community Megaphone OData feed. In my initial experiments, I was rendering the maps using the Bing Maps JavaScript API, and I quickly realized that rendering dozens of interactive maps was not conducive to good performance, and practically speaking, wasn’t necessary to give the user the information I was looking to provide.

Continue reading Reuse in action: Bing Maps REST API and Community Megaphone