JavaScript : relaxing equality

Recently I received a pull request for an issue in cordova.exec on the Windows platform. It seems that a plugin result of type NO_RESULT would not be handled correctly, because NO_RESULT was actually defined as 0, and we were loosely checking along the lines of if(pluginResult.status){...} The pull request added logic to check for undefined like this :

if(pluginResult.status !== undefined){...}

On the surface it looks fine, and status of 0 will still be handled, however, because it is using strict equality comparison, and values of null are possible, and additional check was added :

if(pluginResult.status !== undefined && pluginResult.status !== null){...}

A verbose solution, but it does do the trick.

Ultimately, this is a case where the strict equality check is not helping us. After writing a few tests to ensure I was not misguided, I ended up writing :

if(pluginResult.status != null){...}

The basic equality comparison here will have the same result for undefined and null, so there is no need to test for both. Many times I hear blanket statements like 'always use strict equality' although I think is more important to simply know how and when it applies.

Here are the tests I wrote to verify the behaviour of various comparisons: Note that I also considered using Object.hasOwnProperty as an alternative way of checking if the object had a value, 0 included.

// Loose equality ({status:undefined}).status != null // false ({status:undefined}).status != undefined // false ({status:undefined}).status != 0 // true

({status:null}).status != undefined // false ({status:null}).status != null // false ({status:null}).status != 0 // true

({status:0}).status != null // true ({status:0}).status != undefined // true ({status:0}).status != 0 // false

// Strict equality ({status:undefined}).status !== null // true ({status:undefined}).status !== undefined // false ({status:undefined}).status !== 0 // true

({status:null}).status !== null // false ({status:null}).status !== undefined // true ({status:null}).status !== 0 // true

({status:0}).status !== null // true ({status:0}).status !== undefined // true ({status:0}).status !== 0 // false

// another way ({status:undefined}).hasOwnProperty('status') // true ({status:null}).hasOwnProperty('status') // true ({status:0}).hasOwnProperty('status') // true ({}).hasOwnProperty('status') // false

A PhoneGap+Cordova WP7 Retrospective

The end of an era?

A little over 2 years ago, we announced the arrival of a new PhoneGap target platform; Windows Phone 7. PhoneGap blog post MSDN Blog Post

As of today, we are deprecating Windows Phone 7 as a target platform for Apache Cordova, and therefore PhoneGap as well.  A lot has changed in the last 2 years, with both Windows Phone 8, and Windows 8 coming along, and also getting consumed as Apache Cordova target platforms along the way, it is time for the changing of the guard.  While still available, Windows Phone 7  device use is on the decline.  The low cost Nokia 520 has done a great job, offering an affordable entry into Windows Phone 8 land.  We have seen less and less demand for WP7 features and PhoneGap Build has locked down support for WP7 at version 2.9.0. Here are some interesting stats on worldwide use of Windows Phone devices and versions.

The road to here

In the last 2 years, the Windows Phone 7  UI, then called Metro, has taken over Windows land and is now everywhere from the xbone to the desktop.

The Mango release for Windows Phone 7 brought Internet Explorer 9 to the phone. Up until Mango, hybrid apps were extremely limited by the fact that the WebBrowser control was IE7 under the hood, and did not support any of the standards that we had come to expect in a predominantly WebKit based device browser landscape.

Along the way, there were obstacles, and in many cases, solutions:

Isolated Storage Wars

The way that Windows Phone 7 packages assets as .dll resources means that html/js/css files are not navigable unless they are unpacked to the local file system. This meant that all WP7 PhoneGap apps had to have an additional initialize step to unpack everything. Also, since the dll does not list it's packaged resources, there was an additional build step to run against the project and create a list of everything that needed to be unpacked at runtime.

Untouchable

Touch events, and even mouse events were not supported in WP7. I implemented a workaround which converted native touch events to mouse events which were injected into the browser control and accessible to PhoneGap apps. More info here: Adding Touch Support to WP7

Web-Storage

IE9 supported the Web-Storage API out of the gate, however there were issues with pages loaded from the file:// protocol, because they did not have a domain that IE9 used to sandbox pages. More details here: Implementing WebStorage for PhoneGap

The future, and beyond

I am proud to say that most of the above hybrid app issues that we had to work around in Windows Phone 7, were addressed in Windows Phone 8, and Microsoft has taken great strides in supporting hybrid app development with WinJS for building Windows Store Apps and many more browser improvements in IE10 ( webbrowser control in Windows Phone 8, and Windows 8 ) and IE11 ( webbrowser control in Windows 8.1 and presumably the next version of Windows Phone ).  This is the power of working closely with Microsoft who have done a great job in supporting PhoneGap, and Apache Cordova.  This also fits the original goal of PhoneGap; to 'cease to exist', because the features you need are built into the platform.

Officially we will continue to support developing for Windows Phone 7 until version 3.7.0, which is expected to happen in May 2014.  Greater attention will be given to Windows Phone 8, and Windows 8, so if you were waiting for a reason to update to the new shiny features, it has arrived.

 

[update: fixed typo: mouse events were not supported in WP7 -jm]

 

 

 

 

Kick Backs - WP8 back button handling.

With the PhoneGap Windows Phone Porting Challenge well under way, I felt it would be a good time to take a deeper dive into the hardware back button mechanism that is implemented in Apache Cordova, and how to use it.

“A frequent cause of failing app certification is due to an inappropriate implementation of the back button behavior. ... Developers often forget to verify that their apps works accordingly, especially when porting from other platforms which have different behavior/hardware buttons."

 

- Jean-Christophe Cimetiere, @jccim

Developer Product Marketing, Windows Phone, Microsoft

The default behavior

Out of the box, Apache Cordova for Windows Phone 8 attempts to behave like a typical browser history back button.  If you have implemented multiple pages within your app, and navigated through them, then Cordova library will call window.history.back() automagically for you.  If the page indeed changes because of this action, then the event is cancelled and the WP8 OS does not do anything in response to the button.  If however the page does not change, then the event is not cancelled, and the WP8 OS takes over and performs its default action of exiting your app.  This allows applications built with jQuery Mobile and the like, to function without alteration.

 Providing your own handler

If you would like to override the default behavior of the backbutton in your app, you simply need to add an event listener to the document. Ideally you would do this after the deviceready event has fired, like this :

    document.addEventListener('deviceready',function(){
        document.addEventListener('backbutton',handleBackButton);
    });

    function handleBackButton() {
        // do something other than the default, like undo an operation, 
        // or step backwards through a multi-step operation
    }

The above code will effectively disable the back button.  In order to re-enable it, simply call removeEventListener :

    document.removeEventListener('backbutton',handleBackButton);

It is worth noting that you are responsible for keeping track of your handlers. If you are using inline functions, it will be difficult for you to remove them. You have been warned.

When the document does not contain any backbutton event handlers, it will perform the default behavior,  which is usually exiting your app.

More reading

You can read a bit more about PhoneGap back button handling and everything else at docs.phonegap.com.

http://docs.phonegap.com/en/2.7.0/cordova_events_events.md.html#backbutton

For more details on all Windows Phone Certification and the proper use of the back button, view Microsoft's technical certification requirements

I am excited to see apps get ported for the PhoneGap Windows Phone Porting Challenge If you have issues along the way, I am actively monitoring the phonegap mailing list and I look forward to helping you out if you need it.

As always, I welcome your comments, and questions here, and on twitter. Jesse aka @purplecabbage