Appliness #11 – February 2013

Embed Size (px)

Citation preview

  • 8/13/2019 Appliness #11 February 2013

    1/140

  • 8/13/2019 Appliness #11 February 2013

    2/140

    appliness FEBRUARY 2013 TABLE OF CONTENTS BOOKMARK / SHARE / TO

    DEFERREDS ANDPROMISES INJAVASCRIPT

    MY WORKFLOWFOR DEVELOPINGPHONEGAP APPS

    appliness

    NEWSby

    Brian Rinaldi

    CODING

    jQUERY MOBILEAND BACKBONE

    INTEGRATION

    BACON.JS MAKESFUNCTIONAL

    REACTIVEPROGRAMMING

    SIZZLE

    BUILDING A UNITTEST IN JASMINE,

    PART 1.

    BUBBLING INENYO, PART 2.

    @

    THE FUTURE OFJAVASCRIPT

    @THINGS ABOUT

    THE WEBKITINSPECTOR

    MOBILEAPPS

    ANDROID PUSHNOTIFICATIONS

    WITH PHONEGAP

    FOCUS-ANG

    ULARJS

    INTERVIEWMISKO HEVERY

    BUILDINGHUUUUGE APPS

    WITH ANGULARJS

    RESPONSIVEFORM

    VALIDATIONWEBD

    ESIGN

    FORM ELEMENTSAND CSS3 TOREPLACE JS

    CONDITIONALLOADING WITHMEDIA QUERIES

    ICONS AND ICONFONTS

    MAKING THETRANSITION TO

    DESIGN

    DESIGN IS NOTVENEER

  • 8/13/2019 Appliness #11 February 2013

    3/140

    appliness TUTORIALS JAVASCRIPT BOOKMARK / SHARE / TO

    Deferreds andPromises inJavaScript

    by FlavioCopes

  • 8/13/2019 Appliness #11 February 2013

    4/140

    UTORIALSDEFERREDS AND PROMISES IN JAVASCRIPT

    by FlavioCopes

    2 of 11

    Promises are a relatively new approach to async management, and they can be reallyhelpful to structure your code.

    A Promise is an object representation of an event. In the course of its life, a Promisegoes from a pending state, when its called, to a resolved or rejected state, when itsbeen completed, or it could also stay pending forever and is never resolved.

    Its a sort of new approach to javascript events, but I think it generates way morereadable code, and its less quirky. At the moment there are 2 slightly different mainimplementations of Promises in javascript: those libraries that follow the Promises/Aspec, and jQuery.

    First Ill take jQuery into consideration as its everywhere and I use it, so if you dontwant another external library, you can use it.

    Lets introduce the concept of Deferred. First, a Deferred is a Promise, with in additionthe fact that you can trigger a Deferred (resolve or reject it), while with a Promise, youcan only add callbacks and it will be triggered by something else.

    A Promise, if you want, is a listen-only part of a Deferred.

    A clear example of this is this function:

    varpromise = $(div.alert).fadeIn().promise();

    You can now add .done() & .fail() to handle the callbacks.This is just a call example, promises for animations have become a real deal in jQuery1.8, also with callbacks for progress.

    Another example of a promise is an AJAX call:

    varpromise = $.get(url);

    promise.done(function(data) {});

    INTRODUCTION

    JQUERY PROMISES

    I think it generates waymore readable code, and

    its less quikky.

  • 8/13/2019 Appliness #11 February 2013

    5/140

    UTORIALSDEFERREDS AND PROMISES IN JAVASCRIPT

    A deferred is something you create, set the callbacks and resolve, like:

    vardeferred = new $.Deferred();deferred.done(function(data) { console.log(data) });deferred.resolve(some data);

    The state of a deferred can be triggered using .resolve() or .reject(). Once a deferredstate has been changed to one of the final stages (resolved/rejected), it cant bechanged any more.

    vardeferred = new $.Deferred();deferred.state(); // pendingdeferred.resolve();deferred.state(); // resolved

    We can attach the following callbacks to a promise:

    .done() //will run when the promise has been executed successfully

    .fail() //will run when the promise has failed

    .always() //will run in either cases

    Those callbacks can be called together using .then(), like:

    promise.then(doneFunc, failFunc, alwaysFunc);

    This is just an intro to the jQuery implementation of Promises and Deferreds. Letswrite some real-word examples. (if executing in node, you can import jQuery byusing $ = require(jquery); )

    For example, here we execute a function, and when its finished it calls dfd.resolve().Similar to doing a callback, but more structured and reusable.

    $.when(execution()).then(executionDone);

    functionexecution(data) { vardfd = $.Deferred(); console.log(start execution);//in the real world, this would probably make an AJAX call.

    setTimeout(function() { dfd.resolve() }, 2000);

    returndfd.promise();

    SOME JQUERY EXAMPLES

    3 of 11

  • 8/13/2019 Appliness #11 February 2013

    6/140

    UTORIALSDEFERREDS AND PROMISES IN JAVASCRIPT

    }functionexecutionDone(){ console.log(execution ended);}

    Here the elements of an array are processed, and once all of them are fine (e.g. arequest has returned), I call another function. We start to see the real benefits ofthe Deferred usage. The $.when.apply() method is used to group the dfd.resolve()in the loop.

    vardata = [1,2,3,4]; // the ids coming back from serviceAvarprocessItemsDeferred = [];for(vari = 0; i < data.length; i++){

    processItemsDeferred.push(processItem(data[i]));}$.when.apply($, processItemsDeferred).then(everythingDone);

    functionprocessItem(data) { vardfd = $.Deferred(); console.log(called processItem);//in the real world, this would probably make an AJAX call.

    setTimeout(function() { dfd.resolve() }, 2000);

    returndfd.promise();}functioneverythingDone(){ console.log(processed all items);}

    A slightly more complex example, here the elements of the array are fetched froman external resource, using var fetchItemIdsDeferred = fetchItemIds(data) and

    fetchItemIdsDeferred.done()

    vardata = []; // the ids coming back from serviceAvarfetchItemIdsDeferred = fetchItemIds(data); // has to add the ids to datafunctionfetchItemIds(data){ vardfd = $.Deferred(); console.log(calling fetchItemIds);data.push(1);

    4 of 11

  • 8/13/2019 Appliness #11 February 2013

    7/140

    UTORIALSDEFERREDS AND PROMISES IN JAVASCRIPT

    data.push(2); data.push(3); data.push(4);

    setTimeout(function() { dfd.resolve() }, 1000); returndfd.promise();

    }fetchItemIdsDeferred.done(function() { // if fetchItemIds successful... varprocessItemsDeferred = [];for(vari = 0; i < data.length; i++){

    processItemsDeferred.push(processItem(data[i])); }$.when.apply($, processItemsDeferred).then(everythingDone);

    });

    functionprocessItem(data) { vardfd = $.Deferred(); console.log(called processItem);//in the real world, this would probably make an AJAX call.

    setTimeout(function() { dfd.resolve() }, 2000);

    returndfd.promise();

    }functioneverythingDone(){ console.log(processed all items);}

    Those last 2 examples explain how to compute a for cycle and then wait for theend of the processing execution to do something.

    Its the less hacky way of doing this:

    varallProcessed = false;varcountProcessed = 0;for (vari = 0, len = theArray.length; i < len; i++) { (function(i) { // do things with i if (++countProcessed === len) allProcessed = true; })(i);}

    5 of 11

  • 8/13/2019 Appliness #11 February 2013

    8/140

    UTORIALSDEFERREDS AND PROMISES IN JAVASCRIPT

    Now another example of how Deferreds can be used for: take a look at this

    varinterval = setInterval(function() { if (App.value) { clearInterval(interval);

    // do things }}, 100);

    This is a construct that evaluates a condition; if the condition is true, the codeclears the interval and executes the code contained in the if.

    This is useful for example to check when a value is not undefined any more:

    varDeferredHelper = {

    objectVariableIsSet: function(object, variableName) { vardfd = $.Deferred();

    varinterval = setInterval(function() { if (object[variableName] !== undefined) { clearInterval(interval); console.log(objectVariableIsSet); dfd.resolve() } }, 10);

    returndfd.promise(); },arrayContainsElements: function(array) {

    vardfd = $.Deferred();

    varinterval = setInterval(function() { if (array.length > 0) { clearInterval(interval); console.log(arrayContainsElements);

    dfd.resolve() } }, 10);

    returndfd.promise(); }}varexecuteThis = function() { console.log(ok!);}

    6 of 11

  • 8/13/2019 Appliness #11 February 2013

    9/140

    UTORIALSDEFERREDS AND PROMISES IN JAVASCRIPT

    varobject = {};object.var= undefined;vararray = [];$.when(DeferredHelper.arrayContainsElements(array)).then(executeThis);

    $.when(DeferredHelper.objectVariableIsSet(object, var)).then(executeThis);setTimeout(function() { object.var= 2; array.push(2); array.push(3);}, 2000);

    The above example is in fact 3 examples in one. I created a DeferredHelper objectand its methods arrayContainsElements and objectVariableIsSet are self-explaining.

    Keep in mind that primitive types are passed by value, so you cant do

    varintegerIsGreaterThanZero = function(integer) { vardfd = $.Deferred();varinterval = setInterval(function() {

    if (integer > 0) { clearInterval(interval); dfd.resolve()

    } }, 10);returndfd.promise();

    };varvariable = 0;$.when(integerIsGreaterThanZero(variable)).then(executeThis);

    nor you can dovarobject = null;varvariableIsSet = function(object) { vardfd = $.Deferred();varinterval = setInterval(function() {

    if (object !== undefined) { clearInterval(interval);

    7 of 11

  • 8/13/2019 Appliness #11 February 2013

    10/140

    UTORIALSDEFERREDS AND PROMISES IN JAVASCRIPT

    console.log(variableIsSet); dfd.resolve() } }, 10);returndfd.promise();

    };$.when(variableIsSet(object)).then(executeThis);setTimeout(function() { object = {};}, 2000);

    because when doing object = {}, the object reference is changed, and as Javascriptactually references variables by copy-reference, the reference of the object variable

    inside the variableIsSet function is not the same as the outer object variable.

    A thing I use with Ember.js is

    App.DeferredHelper = {/**

    * Check if an array has elements on the App global object if object* is not set.

    * If object is set, check on that object. */ arrayContainsElements: function(arrayName, object) { vardfd = $.Deferred(); if (!object) object = App;

    varinterval = setInterval(function() { if (object.get(arrayName).length > 0) { clearInterval(interval);

    dfd.resolve() } }, 50);

    returndfd.promise(); },/**

    * Check if a variable is set on the App global object if object* is not set.

    AN EMBER.JS EXAMPLE

    8 of 11

  • 8/13/2019 Appliness #11 February 2013

    11/140

    UTORIALSDEFERREDS AND PROMISES IN JAVASCRIPT

    * If object is set, check on that object. */ variableIsSet: function(variableName, object) { vardfd = $.Deferred(); if (!object) object = App;

    varinterval = setInterval(function() { if (object.get(variableName) !== undefined) { clearInterval(interval); dfd.resolve() } }, 50);

    returndfd.promise(); }}

    so I can do in my client code:

    $.when(App.DeferredHelper.arrayContainsElements(itemsController.content)).then(function() { //do things});

    and

    $.when(App.DeferredHelper.variableIsSet(aVariable)).then(function() { //do things});//&$.when(App.DeferredHelper.variableIsSet(aVariable, anObject)).then(function() { //do things});

    All those examples were made using the jQuery deferreds implementation.Additional resources on them:http://robdodson.me/blog/2012/06/03/make-your-own-jquery-deferreds-and-promises/

    http://msdn.microsoft.com/en-us/magazine/gg723713.aspx

    9 of 11

  • 8/13/2019 Appliness #11 February 2013

    12/140

    UTORIALSDEFERREDS AND PROMISES IN JAVASCRIPT

    If youre not willing to use the jQuery deferred implementation, maybe becauseyoure not using jQuery and loading it just for the deferreds is overkill, or youreusing another library that does not have a deferred implementation, you can useother libraries specialized in this, such as Q, rsvp.js, when.js.

    For example, I have the ID of an item, and I want to call the API endpoint to getmore detail about it. Once the AJAX call returns, continue processing.

    functionprocessItem(item) { vardeferred = when.defer();varrequest = $.ajax({

    url: /api/itemDetails, type: GET data: { item: item } });request.done(function(response) {

    deferred.resolve(JSON.parse(response));});

    request.fail(function(response) {

    deferred.reject(error); });returndeferred.promise;

    }varitem = { id: 1}

    processItem(item).then( functiongotIt(itemDetail) { console.log(itemDetail); }, functiondoh(err) { console.error(err); });

    USING WHEN.JS

    10 of 11

  • 8/13/2019 Appliness #11 February 2013

    13/140

    UTORIALSDEFERREDS AND PROMISES IN JAVASCRIPT

    I got some ID values from a server, process them using the processItem() functionfrom above, and then once finished processing ALL of them, I can do something

    functionprocessItems(anArray) { vardeferreds = [];for (vari = 0, len = anArray.length; i < len; i++) {

    deferreds.push(processItem(anArray[i].id)); }returnwhen.all(deferreds);

    }varanArray = [1, 2, 3, 4];processItems(anArray).then(

    functiongotEm(itemsArray) { console.log(itemsArray); }, functiondoh(err) { console.error(err); });

    The when.js library provides some utility methods such as when.any() and when.some(), that let the deferred callback run when 1) one of the promises has been

    solved 2) at least a specified number of promises have returned.

    Flavio CopesFrontend engineer

    HISBLOG

    TWITTER

    SHARE

    GITHUB

  • 8/13/2019 Appliness #11 February 2013

    14/140

    appliness TUTORIALS JAVASCRIPT BOOKMARK / SHARE / TO

    jQuery Mobile and Back-bone.js Integration with aSimple FAQ App.

    by ThibaultDurand

    jQuery Mobile andBackbone.js Integrationwith a Simple FAQ App.

  • 8/13/2019 Appliness #11 February 2013

    15/140

    UTORIALSJQUERY MOBILE AND BACKBONE.JS WITH A SIMPLE FAQ APP

    by ThibaultDurand

    2 of 10

    This project is hosted on github here: http://github.com/tdurand/faq-app-client-mobile-comparison

    UPDATE (26/10/12) : Jquery Mobile Team added a sample in the offical docs whichis using one of the methods presented below: Backbone Based Routing (+ here youwill found some tips for transition management ) : http://jquerymobile.com/test/docs/

    pages/backbone-require.html

    Disclaimer: Im not an expert on the subject, and maybe Im wrong or incomplete onsome points, I would really appreciate some feedback.

    Context: This small FAQ app will be used in production by Mosalingua, if youreinterested in a great apps to learn languages, you should definitely check out http://

    www.mosalingua.com.

    This project aims to compare two different methods to integrate Backbone.js withjQuery Mobile (currently v 1.1.1).

    Its a basic FAQ visualization app which consume webservice from this project: http://github.com/tdurand/faq-app-server.

    Two different approaches:

    keep jQuery Mobile default router and use the jquery-mobile router project whichextend the native jQMobile router giving the possibility to pass parameters. (Projecton github)

    disable jQuery Mobile default router and use Backbone for routing. (based onaddyosmanI works)

    GETTING STARTED

    ABOUT

    Using the Backbone routingapproach gives you muchmore maintainable code.

  • 8/13/2019 Appliness #11 February 2013

    16/140

  • 8/13/2019 Appliness #11 February 2013

    17/140

    UTORIALSJQUERY MOBILE AND BACKBONE.JS WITH A SIMPLE FAQ APP

    category:function(lang,id,idEntry) { varcategoryView=newCategoryView({id:id,lang:lang,idEntry:idEntry}); faq.appView.show(categoryView); this.changePage(categoryView,transition); $.mobile.showPageLoadingMsg();},

    You can have really cleans and REST Like urls.

    jQuery Mobile Router

    jQM router doesnt give you the possibility to do pretty routing like this. More info

    here on why.

    Example of an url:

    #category?param1=qsj&params2=sj

    The routes declaration looks like this, you specify a regex to get the parameters:

    #index(?:[?](.*))?: { handler: index, events: bs},

    #category(?:[?](.*))?: { handler: category, events: bs}

    And then you can access the parameters in your handlers:

    index:function(type,match){ //Default lang varlang=fr; if(match[1]!==undefined) { varparams=Router.getParams(match[1]); //GET the params

    lang=params.lang;

    } this.indexView=new IndexView({lang:lang});},

    ROUTING : URL HASH UPDATING

    A good web application design rule is that you can bookmark any page. For afront-end application it implies that you can easily manage the window.locationobject to update the current url.

    4 of 10

  • 8/13/2019 Appliness #11 February 2013

    18/140

    UTORIALSJQUERY MOBILE AND BACKBONE.JS WITH A SIMPLE FAQ APP

    Backbone routing

    Backbone provides a really nice way to do it with the navigate function of therouter (http://backbonejs.org/#Router-navigate).

    You can update the url and choose if you want to trigger the route, and even if youwant to add the action in the history.

    In the demo apps is particularly useful to be able to bookmark a particular entry:

    //Update the url without triggering the route faq.routers.router.navigate(#+Entries.lang+/category/+Entries.idCategory+/entry/+expandedEntryId,{replace: true}); //Attach a collapsed handler expandedElement.on(collapse.expanded,function() { //Update the url when collapsing faq.routers.router.navigate(#+Entries.lang+/category/+Entries.idCategory,{replace: true}); $(this).off(collapse.expanded); });

    jQuery Mobile Router

    With jquery mobile router youll need to do all by hand. And yet i didnt find how touse windows.location.replace() without causing a jQM triggering a new rendering.

    //Change url TODO: SEE HOW TO DO NOT TRIGGER ROUTERwindow.location.replace(#category?lang=+Entries.lang+&id=+Entries.idCategory+&idEntry=+expandedEntryId); //Attach a collapsed handler expandedElement.on(collapse.expanded,function(e) { $(this).off(collapse.expanded); window.location.replace(#category?lang=+Entries.lang+&id=+Entries.idCategory);});

    TRANSITIONS MANAGEMENT

    Backbone routing

    I think is the ugliest part of backbone routing based integration.

    5 of 10

  • 8/13/2019 Appliness #11 February 2013

    19/140

    UTORIALSJQUERY MOBILE AND BACKBONE.JS WITH A SIMPLE FAQ APP

    Because you manually change the page in the router , you need to know thetransition at this moment of the execution. But when the handler correspondingto your route is called by the Backbone Router, you do not have this information.

    $.mobile.changePage($(view.el), {

    transition:NEEDTONOWTHETRANSITION, changeHash:false, reverse:true or false});

    TRANSITION AS PARAMETERS

    A solution is to pass the transition as a parameter, its ugly because you polluteyour url with transition data which you need to clean after.

    Router:

    :lang: index,:lang/:transition: index, //Handle specific transition:lang/:transition/reverse/:reverse: index, //Handle reverse

    Links:

    Back //Back button link

    An you handle transition in the router like this

    index:function(lang,transition,reverse){ //Set lang if given if(lang) { this.lang=lang; } //Clean the url ( #fr/slide/reverse/true -> #fr) this.navigate(#+this.lang, {replace: true});

    varindexView=new IndexView({lang:this.lang}); this.changePage(indexView,transition,reverse);}

    In reality, you dont need to specify the transition every time, you can define adefault transition (for example slide) and just specify the transition if you dontwant the default transition. Although for backbutton you must specify the reversetransition

    6 of 10

  • 8/13/2019 Appliness #11 February 2013

    20/140

  • 8/13/2019 Appliness #11 February 2013

    21/140

    UTORIALSJQUERY MOBILE AND BACKBONE.JS WITH A SIMPLE FAQ APP

    JQUERY MOBILE ROUTER

    Like native jQM, youll just need to put a data-transition attribute on the link andjQM will handle the rest.

    Additionally, jQM will detect that you need a reverse transition when you pressback button.

    BACKBONE ROUTING

    Unlike jQuery Mobile Router, you cant trigger the routes handler on jquery mobileevents (backbone trigger the routes on url changes), but you always can access tothis events by putting a handler if you need it.

    JQUERY MOBILE ROUTER

    The main reason is to preserve the granularity offered by jQuery Mobile while givingthe programmer a simple way to tap into unusual page transition states, suchas pageinit or pageremove, as if they were standard routes. The outcome is acontroller which is more powerful and versatile, in the jQM realm, than its purelyhashchange based counterpart.

    With jQuery Mobile Router you can trigger the routes on some precise events:

    bc => pagebeforecreatec => pagecreatei => pageinitbs => pagebeforeshow

    s => pageshowbh => pagebeforehideh => pagehiderm => pageremovebC => pagebeforechangebl => pagebeforeloadl => pageload

    With the transition management this one of the main advantage of using jQueryMobile Router.

    EVENTS

    8 of 10

  • 8/13/2019 Appliness #11 February 2013

    22/140

    UTORIALSJQUERY MOBILE AND BACKBONE.JS WITH A SIMPLE FAQ APP

    REUSABILITY

    Using backbone for routing clearly separe your view logic from you app logic, youcan easily reuse you code to build a new interface (for Desktop, Tablet )

    COMPABILITY

    Do not use jQM default routing and you can forget the B and C grade support :http://jquerymobile.com/demos/1.2.0/docs/about/platforms.html

    Depending on your project requirements, both solution can be adopted. If you aredoing only a phonegap app, maybe you just dont care to have pretty urls, and youwant to use most of the jQM features.

    Using Backbone for routing makes use of jQMobile only as an UI framework fromthat you can switch to build other interface to your app.

    I think that for a big project, backbone routing approach will gives you a codemuch more maintainable, and if you are doing a web app clean url are priceless.

    I will really appreciate some feedback!

    From Andrea Zicchetti, main developer of jquery mobile router.

    I was discussing certain aspects of routing with John Bender, the jQM developerresponsible of these things (for the 1.2.1 release he promised to clean things upand fix some nasty bugs related to routing), and I think he should read from yourarticle where the framework fails to support programmers:

    clean urls bookmarking of internal page states

    MISCELLANEOUS

    CONCLUSION

    FEEDBACK

    9 of 10

  • 8/13/2019 Appliness #11 February 2013

    23/140

  • 8/13/2019 Appliness #11 February 2013

    24/140

    appliness TUTORIALS JAVASCRIPT BOOKMARK / SHARE / TO

    Bacon.js Makes FunctionalReactive Programming Sizzle

    by VilleLautanala

  • 8/13/2019 Appliness #11 February 2013

    25/140

    UTORIALSBACON.JS MAKES FUNCTIONAL REACTIVE PROGRAMMING SIZZLE

    by VilleLautanala

    2 of 6

    Like most other JavaScript developers, weve been in a callback hell. Functional ReactiveProgramming (FRP) is one, and in ouropinion rather powerful, tool to improvethe structure of your web app. This blogpost introduces FRP concepts and benefitswith Bacon.js, an FRP library for bothbrowsers and server-side JS. Weve been

    using Bacon.js in the new Flowdock.

    Reactive programming is different fromevent-driven programming in the sensethat it focuses on data flows and propagationof change instead of handling single events.For example, in an imperative world, therecould be a statement that sums up two variables and produces a third variable. If eitherof the variables change, you wouldnt expect the value of the result variable to change.

    If youre using reactive building blocks, the result variable would always be the sum ofthe two variables. In this sense, reactive programming is almost like a spreadsheet.

    FRP implements reactive programming with functional building blocks. Referentialtransparency is strictly enforced, which prohibits the use of variables. An alternative wayhas to be used to handle time-varying values. The main concepts in FRP are properties(not to be confused with JavaScript properties) and event streams. There are differentnames for these in different implementations. Signal and event are commonly used,but well stick with Bacon.js nomenclature.

    EventStreams are sources of events. These can be mouse clicks, keyboard events orany other input. The power of EventStreams is that they are composable. It is possibleto use similar tools that are used to handle arrays for event streams: you can filterevents, map event values to other values or reduce events to a property.

    Property is used as an abstraction for a time-varying value. Properties are similar toEventStreams, but they also have the notion of current value. Most of the functionalityis shared with EventStreams.

    GETTING STARTED

    Photo by the Pug Father

    At Flowdock, weve beenusing Bacon to handle al

    kinds of things...

  • 8/13/2019 Appliness #11 February 2013

    26/140

    UTORIALSBACON.JS MAKES FUNCTIONAL REACTIVE PROGRAMMING SIZZLE

    Lets try out this FRP thing by figuring out if the user is active on a web page. This issomething weve had to do in Flowdock to determine what kind of notifications weshould play. For example, we dont want to bother users with sound notificationswhen they are participating actively in the current discussion.

    The easiest thing that could work is to use focus and blur events. A pretty standardapproach to this, using jQuery would be

    varfocused = true;$(window).on(blur, function() { focused = false; });$(window).on(focus, function() { focused = true; });

    Not that bad, but how about the FRP approach then?

    varblur = $(window).asEventStream(blur).map(function() { returnfalse;});varfocus = $(window).asEventStream(focus).map(function() { returntrue;});varfocused = focus.merge(blur).toProperty(true);

    Two Bacon.js EventStreams are defined: blur that emits falses and focus that

    emits trues. Then the streams are combined using using merge and converted toa Property that captures the value of focus. true is defined as initial value. If youwant to inspect the value, a listener to the Property can be bound using onValue

    focused.onValue(function(focus) { console.log(focus, focus); });

    Theres one gotcha: Bacon.js is lazy. Before the stream or property has anysubscribers, it wont do anything. The current value of the property wont updateand event listeners arent bound to the DOM. This can be very useful since it means

    creating streams causes zero overhead.

    The focus/blur idea to handle activity state is usually not good enough. The focusand blur events arent always reliable and we wont have any idea if the user hasleft the computer three hours ago.

    How about using keyboard and mouse activity then? Lets say that users are active

    STREAMS AND PROPERTIES IN BACON

    HANDLING STATE WITH SWITCHING STREAMS

    3 of 6

  • 8/13/2019 Appliness #11 February 2013

    27/140

    UTORIALSBACON.JS MAKES FUNCTIONAL REACTIVE PROGRAMMING SIZZLE

    when they have moved the mouse pointer or pressed some key within the last 30seconds.

    For comparison, this could be implemented in plain old jQuery as follows:

    varactive = true;vartimeout = null;functionsetInactive() { active = false;}

    $(window).on(keydown mousemove, function() { active = true; clearTimeout(timeout); timeout = setTimeout(setInactive, 30000);})

    A Bacon EventStream of user activities is a good start.

    varactivity = $(window).asEventStream(mousemove keydown)

    The stream only contains events of the positive case. Negative case requires youto detect when there is no activity. Heres where stream switching becomes useful.

    varactive = activity.flatMapLatest(function(event) {

    returnBacon.once(true).merge(Bacon.later(30000, false));}).toProperty(true);

    Here stream switching is used to implement state in a functional world. In Bacon,flatMap maps each event in the stream to a new stream of events. flatMapLatestworks like flatMap, except that only events from the latest spawned stream areincluded. So, the value is true for 30 seconds after the last user interaction.

    This isnt the only, or even the simplest, way to implement such an activity property.

    Bacon throttle could be used to only emit events after a quiet period.

    activity.map(function() { returntrue; }).merge( activity.throttle(30000).map(function() { returnfalse; })).toProperty(true);

    If this is compared to the event-driven solution, youll see that the FRP solutionlooks more desirable. There are less moving parts and the code is more focusedon the logic rather than implementation details.

    4 of 6

  • 8/13/2019 Appliness #11 February 2013

    28/140

  • 8/13/2019 Appliness #11 February 2013

    29/140

    UTORIALSBACON.JS MAKES FUNCTIONAL REACTIVE PROGRAMMING SIZZLE

    Decoupling the stream and application logic also makes it easier to test componentsthat depend on the activity. You can give the state as argument to other componentsand dont need to write complex objects to encapsulate the state.

    At Flowdock, weve been using Bacon to handle all kinds of things: autocompletingUI components with asynchronous results, synchronising Backbone models overSocket.IO and handling keyboard shortcuts.

    This blog post didnt cover much of the Bacon.js API. The Bacon.js readmeis themost comprehensive source of documentation. The Bacon.js wikihas also excellent

    visualisations of the few important methods and their implications.

    ON THE ROAD TO A BYPASS SURGERY

    Ville LautanalaDeveloper at Flowdock

    HISBLOG

    TWITTER

    SHARE

    GITHUB

  • 8/13/2019 Appliness #11 February 2013

    30/140

    appliness TUTORIALS JAVASCRIPT BOOKMARK / SHARE / TO

    Building a Unit Testin Jasmine, Part 1.

    by DavidPosin

  • 8/13/2019 Appliness #11 February 2013

    31/140

    UTORIALSBUILDING A UNIT TEST IN JASMINE, PART 1

    by DavidPosin

    2 of 4

    (Thanks to Dustin Butler for the inspiration that led me down this path. His great andmore in-depth article is at Unit Test JavaScript Applications with Jasmine)

    Unit testing and I have had a tumultuous affair until now. Every few months I wouldpick up a book, go on a blog reading binge, or try out a framework. It would neverwork out. I would get frustrated or work would intervene and off I went. Unit testingand I were almost fated to always be apart...

    An opportunity came at work to create a new feature on our web platform. I decidedto take a chance and build it from unit tests. It was a great opportunity to start cleanwith very few dependencies to worry about. The lack of entanglements made it easierfor me to understand how unit testing would work to describe this new piece.

    After some web research, I decided on Jasmine. I dont know enough about unittesting yet to speak about which platforms are best suited for what. What I do knowis that Jasmine was recommended in some trustworthy sources, and I could grasp its

    syntax readily. My first hurdle was understanding how it worked. Beginning can bethe hardest part, so I started simple....2+2=4.

    The first step was to create a testing space and adding the necessary Jasmine files to it.The latest zip can be downloaded at https://github.com/pivotal/jasmine/downloads.The files that are necessary to get started are:

    SpecRunner.html jasmine.css jasmine.js jasmine-html.js

    GETTING STARTED

    Unit testing and I havehad a tumultuous affai

    until now.

  • 8/13/2019 Appliness #11 February 2013

    32/140

    UTORIALSBUILDING A UNIT TEST IN JASMINE, PART 1

    I put everything in one folder when I first started with Jasmine. Later, I created anappropriate folder structure to host my tests. There are three parts to any test:

    HTML - The tests are started by loading an html page that builds the Jasmineenvironment and executes the tests

    Spec - describes the tests and how they should run Source - The code being tested

    First, I created a new JavaScript file for my first Spec. Then, I went to add it to theJasmine test environment on the HTML page. The HTML page will need to accessthe new Spec file and the Source to test. This is accomplished through simplescript tags. The sample HTML file, SpecRunner.html included in the download, has2 comment lines that call out a place to put those tags.

    With the reference created, I moved on to editing my Spec file. The first functionis describe. Describes are headings you can use to organize multiple tests into

    logical groupings, or suites. For example, I might have a describe for a simpleobjects Attribute Tests and another for Function Tests. I used Simple Testfor this example. The describe is a closure so the second parameter is a function.

    The it goes inside this closure. it is the specific test(s) you are going to run.it is also a function with a closure. The first parameter is what will be returned toyou on a successful test. This example returns 2+2=4 on a successful test. Thesecond parameter is the function that does the work.

    A lot of things can happen inside an it. Primarily, a thing is expected tohave a predetermined result. This is the purpose of the expect function. Theexpect function captures the result of the process passed into it. The expect thenmatches that actual result against the expected result. If the result matches theexpected result, then the test passes. If not, the test fails. The matchers I haveused most often are toBe and toEqual. The test can be read as I expect the resultto be or I expect the result to equal. The difference between the two is typecomparison. toBe performs implicit type conversion (==), and toEqual performs

    3 of 4

  • 8/13/2019 Appliness #11 February 2013

    33/140

    UTORIALSBUILDING A UNIT TEST IN JASMINE, PART 1

    no type conversion (===).

    It helps me understand my tests by reading them in plain language. One of thereasons I like Jasmine is how easy this is. The simple test I put together for thispost can be read as:

    I have a simple test running to check that 2 + 2 = 4, and I expect my inline function to returna 4 when run.

    Next week, we will take this and start abstracting it out.

    David PosinJavaScript Architect at

    Scrollmotion, Inc.

    HISBLOG SHARE

    GITHUBGOOGLE+

  • 8/13/2019 Appliness #11 February 2013

    34/140

    appliness TUTORIALS JAVASCRIPT BOOKMARK / SHARE / TO

    Bubbling in EnyoPart 2.

    by DavidPosin

  • 8/13/2019 Appliness #11 February 2013

    35/140

    UTORIALSBUBBLING IN ENYO, PART 2

    by DavidPosin

    2 of 7

    We looked at a simple example in Part 1. A button component sent an event up theobject hierarchy until it was captured by the App kind and resolved. Wouldnt it begreat if we could use the same BubbleButton kind in 2 different hierarchies and get 2different results? Yes it would; so lets do that.

    Lets start by revisiting the BubbleButton:

    enyo.kind({ name: BubbleButton, kind: enyo.Button, handlers: { ontap: tapped }, tapped: function() { this.setAttribute (disabled, true); this.bubble(onUpdate); returntrue; }

    });

    The BubbleButton is an extended type from the base enyo.Button type. This meansthat all the standard methods and functionality of a button are provided automaticallywhen a new instance is created. This includes the instance getting create, destory,and render methods. I have removed all three explicitly from the button definition foreasier reading and less code. They will be inherited when the time comes. The buttonis still listening for a tap event which is defined in the handlers section.

    handlers: { ontap: tapped },

    The tapped function will run when the button receives the ontap event. The ontapis an event we get for free from the Enyo framework. The ontap event blurs the linebetween mobile and desktop, and is fired by both touch screen taps and mouse clicks.One change has been made since last time. The tapped function now includes this line:

    this.setAttribute (disabled, true);

    Wouldnt it be great iwe could use the same

    BubbleButton in 2 hierarchies...

  • 8/13/2019 Appliness #11 February 2013

    36/140

    UTORIALSBUBBLING IN ENYO, PART 2

    The BubbleButton will be assigned the html disabled attribute after being pressed.The vanilla disabled attribute is used so it will only work on browsers that supportthat property. I cant think of a browser that doesnt support the disabled propertybut it is worth mentioning. The setAttribute method tells Enyo to immediately

    update the UI representation of this component. A separate render call is notrequired.

    With this in place, there is a way to verify which one of two ontap functions is beingexecuted. It will be possible to confirm which hierarchy the button is affecting. Theactive button will turn gray and non-interactive.

    The tapped function will cause the onUpdate event to start bubbling up the objecthierarchy. The BubbleButton is still fairly generic to this point. This supports the

    reuse model that is so integral to Enyo. The BubbleButton can be placed into anyapp with no effort, and provides a simple set of localized functionalty.

    The example includes two new kinds: BubbleDiv and BubbleParagraph. TheBubbleDiv looks like:

    enyo.kind({ name: BubbleDiv, kind: enyo.Control,

    tag: div, handlers: { onUpdate: updateDiv }, components: [{ tag: p, name: divParagraph, content: Blank Div },{

    kind: BubbleButton,

    content: Press Me in this Div }], updateDiv: function() { this.$.divParagraph.content = Not A Blank Div Anymore; this.render(); returntrue; }});

    3 of 7

  • 8/13/2019 Appliness #11 February 2013

    37/140

    UTORIALSBUBBLING IN ENYO, PART 2

    The BubbleDiv explicitly identifies its tag as a div. This tells Enyo to render thecomponent as an html div. A div is the default tag for any component without a tagexplictly set to something else. This makes setting the tag redundant but is doneto provide a visual differential for us to read the 2 new kinds together. There aretwo components contained within this div object. The first component is a simple

    paragraph:

    { tag: p, name: divParagraph, content: Blank Div}

    Giving the component a tag attribute will set the html tag, just like the div tag inthe BubbleDiv. The name attribute gives us a way to reference the paragraph incode. The name is not the rendered id. The id attribute can be set explicitly but Ifind that is not a good idea. Enyo ends up needing the id to do its own magic. Thereference via its name is maintained in the Enyo framework so we rarely need toworry about the actual id. Finally, the content is what is put into the paragraph. Theparagrapgh will render like this:

    Blank Div

    The second component is our BubbleButton component. The button inherits theproperties of the regular enyo.button which includes automatic handling of thecontent property. Setting content in this case is what will appear on the button.

    { kind: BubbleButton, content: Press Me in this Div}

    The most important part of the BubbleDiv for our purposes is the handler function:

    handlers: { onUpdate: updateDiv },

    updateDiv: function() { this.$.divParagraph.content = Not A Blank Div Anymore; this.render(); returntrue; }

    4 of 7

  • 8/13/2019 Appliness #11 February 2013

    38/140

    UTORIALSBUBBLING IN ENYO, PART 2

    The BubbleButton will bubble up the onUpdate event. Since the BubbleDiv containsa BubbleButton it can choose to capture that event. This is accomplished by addinga handler for onUpdate to our BubbleDiv. When an event is captured, the onUpdatehandler tells Enyo to call the updateDiv function. The updateDiv function is goingto change the contents of the paragraph inside the div.

    The function is going to get the paragraph by using the this.$ shorthand. Theshorthand allows access to the current components contents, including othercomponents. It is possible to retrieve a component from inside another componentif you know its name. In this case, we are looking for divParagraph which is thename we gave the paragraph inside of the BubbleDiv. Using dot notation wegrab the divParagraph component inside this component and change its content(this.$.divParagraph.content). Since this modifies the contents of an html property,we will need to re-render this component. The BubbleDiv is re-rendered and the

    onUpdate event is stopped by returning true.

    The BubbleParagraph is very similar to our BubbleDiv:

    enyo.kind({ name: BubbleParagraph,kind: enyo.Control,

    handlers: { onUpdate: updateParagraph },

    components: [{ tag: p, name: paragraph, content: Blank Paragraph },

    { kind: BubbleButton, content: Press Me in this Paragraph }], updateParagraph: function() {

    this.$.paragraph.content = Not A Blank Paragraph Anymore; this.render(); returntrue; }});

    The crucial difference between the two kinds is in the updateParagraph function.The updateParagraph looks for a different component, and changes the content tosomething different than the BubbleDiv. Pushing the button in the BubbleParagraphchanges the content to Not a Blank Paragraph Anymore. The most important

    5 of 7

  • 8/13/2019 Appliness #11 February 2013

    39/140

    UTORIALSBUBBLING IN ENYO, PART 2

    feature of both is the BubbleButton. Both kinds use the same BubbbleButton kind.Despite this simularity, the result of pushing the button is different. Use the jsFiddlebelow to try it out. In summary, two different kinds with two different behaviorsusing the same button.

    The power of Enyos object and bubbling system have allowed the creation of anew reusable component in a few lines of code. The BubbleButton has been writtenonce and used twice. An Enyo kind definition is very narrative in structure whichmakes it easy to maintain and understand. An Enyo kind can exist as a targetedevent emitter with the bubble functionality. The simple way that a small definitioncan unlock so much potential is one of my favorite features of the Enyo2 framework.

    6 of 7

  • 8/13/2019 Appliness #11 February 2013

    40/140

    UTORIALSBUBBLING IN ENYO, PART 2

    In Part 3, the example will be expanded to allow the onUpdate event to continuepast the direct parent to be handled elsewhere.

    David PosinJavaScript Architect at

    Scrollmotion, Inc.

    HISBLOG

    GOOGLE+

    SHARE

    GITHUB

  • 8/13/2019 Appliness #11 February 2013

    41/140

    appliness TUTORIALS JAVASCRIPT BOOKMARK / SHARE / TO

    The future of JavaScript:

    a CoffeeScript-likeworkflow

    by Dr. AxelRauschmayer

  • 8/13/2019 Appliness #11 February 2013

    42/140

    UTORIALSTHE FUTURE OF JAVASCRIPT

    by Dr. AxelRauschmayer

    2 of 7

    ECMAScript 6 will bring many new features to the language. However, it will be yearsbefore we can rely on it being supported in most browsers that are in use. This postexamines tools that will allow us to program with ECMAScript 6 much sooner.

    JavaScript is a web programming language. You will thus always encounter a wide

    variety of language versions:

    Applications are written in many different ECMAScript versions. Even a singleapplication is likely to be a mix of several versions, considering that it often includeslibraries and external code (e.g. for analytics).

    Many different browser versions are in use, even quite old ones. In every browser,there is exactly one version of ECMAScript available. Users have little control overwhich version it is, because browsers often update themselves automatically (making

    new versions forced upgrades).

    This imposes constraints on what can be done with ECMAScript 6: First, this versioncannot introduce any changes that would break existing code. Second, app developerswill have to wait years until they can use it when it is supported by most browsers.

    It is interesting to compare that with how things work with traditional programminglanguages: You have much more control. End users decide when to upgrade engineand app versions. As an app developer, you can usually demand that a reasonably

    recent version of a language be installed and can target that version. Breaking changesto a language can be introduced by letting users install two versions in parallel (whichis what Python did with version 3).

    One possible solution is to simply annotate each piece of code with a language version.That would allow new versions to introduce breaking changes, because those wontaffect the old code. However, there are two problems with this approach: First, its a

    ECMAScript

    EVOLVING A WEB PROGRAMMING

    WHY NOT VERSIONING?

    There are goodtimes ahead for

    JavaScript.

  • 8/13/2019 Appliness #11 February 2013

    43/140

    UTORIALSTHE FUTURE OF JAVASCRIPT

    usability problem who wants to start each code fragment with a version number?For ECMAScript 5 strict mode, you have to do that and it hampered its adoptionrate. Second, its a maintenance problem you have to maintain several languageversions in parallel inside a single engine. That would make browsers even morebloated. Lastly, we still havent solved the issue of app developers not being able

    to use ECMAScript 6 right away. For the remainder of this post, we will focus onthis issue and ignore the issues that engines are faced with.

    If we want to use ECMAScript 6 as app developers, but still want to run our softwareon old browsers, we only have one option: compile ECMAScript 6 to ECMAScript3 (possibly ECMAScript 5 in 12 years). The precedent is obvious: CoffeeScripthas been doing this since December 2010. With source maps, you can even debug

    its code in the browser the JavaScript it has been compiled to is hidden fromyou. Several ECMAScript 6 features have been influenced by CoffeeScript (arrowfunctions, classes). Then why not use CoffeeScript and be done with it? There areseveral reasons:

    - Different syntax:when CoffeeScript was created, giving it a different syntaxmade sense, because it wasnt JavaScript and pretending so would have clashedwith future versions of that language. However, now that CoffeeScripts mostimportant fixes are available in ECMAScript 6, we can go native again. Thispoint is obviously controversial people who like CoffeeScript often do sobecause of its different syntax, not despite it. I, however, agree with NicholasZakas assertion:

    There is a very real problem in the web development industry and that problemis a significant lack of good JavaScript developers.

    [...] [I] want the web as a whole to continue to grow and get better, and that onlyhappens when we have more competent developers entering the workforce.

    I see compile-to-JavaScript languages as a barrier to that goal. We shouldbe convincing more people to learn JavaScript rather than giving them moreoptions to not write JavaScript. I often wonder what would happen if all of theteams and companies who spent time, energy, personnel, and money to developthese alternatives instead used those resources on improving JavaScript andteaching it.

    SOLUTION FOR APP DEVELOPERS: A COFFEESCRIPT-LIKE WORKFLOW

    3 of 7

  • 8/13/2019 Appliness #11 February 2013

    44/140

    UTORIALSTHE FUTURE OF JAVASCRIPT

    - No compilation during development: Soon, youll be able to use an ECMAScript6 capable browser during development and wont have to compile. Its a smallthing, but still less complexity to worry about.

    - New features: ECMAScript 6 can do things that CoffeeScript cant. Two examples:

    modules and generators.

    There are already several solutions for compiling ECMAScript 6 to ECMAScript 3(or ECMAScript 5):

    Traceur: compiles ECMAScript 6 to ECMAScript 3, on the fly. You can thus alreadyplay with ECMAScript 6 now. Dynamic compilation is an interesting alternative

    to compiling before deployment. Possible problems are performance anddebugging.

    Harmonizr: statically compiles to ECMAScript 3. It supports ECMAScript 6features such as modules, arrow functions and classes.

    TypeScript: statically compiles to ECMAScript 3 and has several advancedfeatures, some of them borrowed from ECMAScript 6 (classes, modules).Interestingly, feedback from TypeScript now helps with evolving ECMAScript.Issues encountered here let us discover potential problems with ECMAScript 6 before it exists. Note that TypeScript is not always completely compatible withECMAScript 6 (especially w.r.t. how it handles private properties).

    Esprima: Ariya Hidayat has written articles on how to use his ECMAScript parserEsprima to compile ECMAScript 6 modules and classes to earlier ECMAScriptversions.

    Possibly the most difficult thing for compilers will be how to translate the block-scoped let variable declarations to the function-scoped var declarations. Forexample, the following code can remain largely unchanged, if tmp isnt used outsidethe then-block.

    // ECMAScript 6 functionfoo(x, y) { if (x === 1) {

    COMPILING ECMASCRIPT 6 TO ECMASCRIPT 3

    COMPILING LET DECLARATIONS

    4 of 7

  • 8/13/2019 Appliness #11 February 2013

    45/140

    UTORIALSTHE FUTURE OF JAVASCRIPT

    let tmp = x + 1; ... } }

    This compiles to:

    // ECMAScript 3 functionfoo(x, y) { if (x === 1) { vartmp = x + 1; ... } }

    However, if tmp is used elsewhere then things are more complicated:

    // ECMAScript 6 functionfoo(x, y) { if (x === 1) { let tmp = x + 1; ... } if (y === 1) { let tmp = y + 1; ...

    } }

    Then you have the option to rename tmp:

    // ECMAScript 3 functionfoo(x, y) { if (x === 1) { vartmp_1 = x + 1;

    ... } if (y === 1) { vartmp_2 = y + 1; ... } }

    Or you can insert IIFEs:

    5 of 7

  • 8/13/2019 Appliness #11 February 2013

    46/140

    UTORIALSTHE FUTURE OF JAVASCRIPT

    // ECMAScript 3 functionfoo(x, y) { if (x === 1) (function() { vartmp = x + 1; ...

    }()); if (y === 1) (function() { vartmp = y + 1; ... }()); }

    ECMAScript 6 will also have several useful additions to the standard library. Forexample: a map data structure (with arbitrary keys, as opposed to the string-onlykeys of objects) and additional string methods (startsWith(), endsWith(), repeat()etc.). Most of them can be shimmed on ECMAScript 5 an earlier via a library.ECMAScript 6 compilers will probably provide this functionality in the same manner.

    But when do we get to use ECMAScript 6 natively? I see three options:

    1. Wait until ECMAScript 6 is the dominant version, switch to it completely. Thatwill take a while.

    2. Dynamically feature-detect what a browser supports and shim less functionality.

    3. Determine what ECMAScript version a browser supports before deliveringJavaScript source files from the server. If it supports ECMAScript 6, deliver theoriginal source code. If it doesnt, deliver the compiled source code.

    As far as I can tell, implementing (3) is currently difficult. Maybe there should bebetter support for it in browsers (by sending the supported ECMAScript versionto the server?).

    There are good times ahead for JavaScript. ECMAScript 6 will introduce manygreat features, compilation will ensure that well actually be able to program with

    THE STANDARD LIBRARY

    USING NEW LANGUAGE FEATURES DIRECTLY

    CONCLUSION

    6 of 7

  • 8/13/2019 Appliness #11 February 2013

    47/140

    UTORIALSTHE FUTURE OF JAVASCRIPT

    them. If you want to find out what ECMAScript 6 can do, take a look at the guideto posts about ECMAScript.next (ECMAScript 6s code name) on 2ality.

    Dr. Axel Rauschmayer

    Consultant for JavaScript

    HISBLOG

    TWITTER

    SHARE

    GITHUB

  • 8/13/2019 Appliness #11 February 2013

    48/140

    appliness TUTORIALS JAVASCRIPT BOOKMARK / SHARE / TO

    My Workflow forDeveloping PhoneGapApplications.

    by AndrewTrice

  • 8/13/2019 Appliness #11 February 2013

    49/140

    UTORIALSMY WORKFLOW FOR DEVELOPING PHONEGAP APPLICATIONS

    by AndrewTrice

    2 of 16

    I am asked all the time How do I get started developing PhoneGapapplications?.My normal answer is to advise people to check out the PhoneGap Getting StartedGuides, which provide a great starting point for every platform. However after furtherthought, Im not sure this is always what people are asking. Rather than how do I getstarted?, I think people are often looking for insight into the workflow for developingPhoneGap applications. Everything from tools to developer flow, to getting the appon devices. The Getting Started Guides are essential for setting up the initial project

    structure, but once you get that setup, you might be wondering what do I do next?.In this post, Ill try to shed some light on the workflow and tools that I use whendeveloping PhoneGap applications.

    First and foremost it is essential to have at least some kind of idea what you aregoing to build before you build it. If you just start hacking things together without a

    plan, the final result is seldomly great. Complete (pixel perfect) UI/UX mockups arefantastic, but you dont have to have a fully polished design and screen flow. Justhaving wireframes/sketches are a great start. Heck, even a sketch on a napkin is betterthan starting with nothing.

    The UX design/wireframes help you understand what you application should be doingfrom the users perspective, which in turn helps you make decisions on how you tacklea project. This can be purely from a HTML level, helping you figure out how you shouldposition DOM elements and/or content. Or, it can help you gauge your projects technical

    complexity How many moving parts do you have, how much of the app is dynamicor asynchronus, or how do different visual elements need to work together? You canleverage this design/mockup to analyze the needs of your application and determine ifa particular framework/development methodology is a best fit (Bootstrap, Backbone.

    js, Knockout.js, Sencha,jQuery Mobile, Angular.js, etc).

    When working with a designer, I use Adobes Creative Suite Tools for pretty mucheverything wireframes, UI/UX designs, chopping up assets, etc Im currently workingon a project that was designed by the talented Jonifrom Adobe XD. Joni designed

    GETTING STARTED

    KNOW WHAT YOURE GOING TO BUILD BEFORE YOU BUILD IT

    Ill try to shed some lighon the workflow and tools

    that I use when developingPhoneGap applications.

  • 8/13/2019 Appliness #11 February 2013

    50/140

    UTORIALSMY WORKFLOW FOR DEVELOPING PHONEGAP APPLICATIONS

    everything in Creative Suite, and Im using Photoshop to view screen flows andextract UI assets for the actual implementation.

    UI Mockups in Photoshop

    3 of 16

  • 8/13/2019 Appliness #11 February 2013

    51/140

    UTORIALSMY WORKFLOW FOR DEVELOPING PHONEGAP APPLICATIONS

    Screen Flow in Photoshop

    Note: This app will also be free and open source as a sample/learning resource forPhoneGap, including all of the design assets Ill follow up with another post onthis later, once the app is available in the app stores.

    If you arent a graphics person, or dont have creative suite, there are a bunch ofother tools that you can use for wireframing and/or sketching (but cmon, CreativeCloudis only $50 a month). Here are several Ive used with great success, but thisis not a comprehensive list at all:

    OmniGraffle - A drag & drop wireframing tool for OS X. This is fantastic forwireframing or documenting screen flows. In fact, the screen flow image shownin Photoshop above was originally composed in Omnigraffle, using the mockupscreated in Photoshop.

    Visio- A powerful drag & drop wireframing/design tool for Windows much likeOmniGraffle, but for windows.

    PowerPointor Keynote- These arent just for presentations. They can be reallyuseful for putting together screen flow diagrams, or annotating images/content.

    4 of 16

  • 8/13/2019 Appliness #11 February 2013

    52/140

    UTORIALSMY WORKFLOW FOR DEVELOPING PHONEGAP APPLICATIONS

    Often people like to sketch out ideas & wireframes on their tablets, here are a fewtools that I use for that:

    Adobe Touch Apps Adobe Ideas can be great for digitally sketching ideas. iBrainstorm A great app for collaboratively taking notes and sketching. Im

    partial to this one b/c used to be on the dev team, and I wrote a good chunk ofthe graphics sketching logic.

    There are a bunch of other tablet sketching apps out there, but I havent usedmost of them.

    Coding environments are a tricky subject. There is no single solution that meets theexact wants and needs for everyone. Some people chose lightweight text editors,some people chose large-scale IDEs, some people use designer-centric tools, andmany of these choices are dependant upon which operating system you use oryour background as a designer or developer. Since PhoneGap applications arereally just editing HTML, CSS & JavaScript, you can use whatever editor you want.In fact, I know a several people that use vim as their primary editor.

    LARGE-SCALE IDES

    Im a bigger fan of of using a complete IDE(integrated development environment)than I am of a lightweight editor, simply b/c IDEs tend to have hooks into morefeatures/languages, etc I know people complain about startup time, but there isno startup time if you leave it open all the time.

    There are a few catches when talking about IDEs with PhoneGap. The first is thatif you want to deploy anything locally to devices (without using PhoneGap Build),you have to delpoy using the IDE for the particular platform that you are targeting.That means Xcode for iOS, Eclipse for Android, or Visual Studio for Windows Phone,etc However if you wish, you can use your editor of choice, and just use the IDEto deploy to devices locally. You can even share source code across several IDEinstallations using symlinks (which I describe here). I very often use this type of aconfiguration to share code between Xcode, Eclipse, and WebStorm.

    My preference for coding PhoneGap applications is to use WebStormby JetBrains.WebStorm has great code-hinting (even for your own custom JS and 3rd party

    CODING ENVIRONMENT

    5 of 16

  • 8/13/2019 Appliness #11 February 2013

    53/140

    UTORIALSMY WORKFLOW FOR DEVELOPING PHONEGAP APPLICATIONS

    libraries), great refactoring, hooks into Git, CVS, or SVN repositories, and is a verymature IDE.

    WebStorm IDE

    I tend to use this as my primary coding tool, then switch to Eclipse or Xcode whenI want to locally deploy to a device for testing. When using PhoneGap Buildtosimplify cross-platform compilation, I just push the code to git, then recompile viaPhoneGap Build.

    Im not a fan of Xcodes HTML/JS editing, and havent found an HTML/JS pluginfor Eclipse that I really like. To target Windows devices, I use Visual Studio.

    LIGHTWEIGHT EDITORS

    Im a bigger fan of larger IDEs than lightweight editors, but Adobe Edge Code(also known as Brackets) is a great lightweight editor for quick edits. Edge Code/Brackets is an open source HTML/JS editor that supports live editing in the browserand inline editors for CSS styles, without leaving your HTML files. If you tried Edge

    6 of 16

  • 8/13/2019 Appliness #11 February 2013

    54/140

    UTORIALSMY WORKFLOW FOR DEVELOPING PHONEGAP APPLICATIONS

    Code Preview 1, but werent sold on it, you should try Edge Code Preview 2. Theteam has come a long way very quickly. Its fast, easy to use, and there is a pluginto tie it into PhoneGap Build. I sometimes use this for quick edits.

    Adobe Edge Code

    Edge Code/Brackets also has a thriving open source project, and encourages youto get involved and help contribute.

    There are tons of other lightweight editors out there, and everyone has theirfavorite. As long as youre happy with the tool, and it can edit text (HTML, CSS, JS)files, you can use it to build PhoneGap applications.

    7 of 16

  • 8/13/2019 Appliness #11 February 2013

    55/140

    UTORIALSMY WORKFLOW FOR DEVELOPING PHONEGAP APPLICATIONS

    DESIGNER-FRIENDLY EDITORS

    Im not necessarily the primary target for Dreamweaver, but it has some nicefeatures. Dreamweaver gives you a great programming environment plus a

    WYSIWYG editor for HTML experiences. It also features PhoneGap Build integrationdirectly inside the coding environment. If youre used to Dreamweaver for creatingweb experiences, you can continue to use it and target mobile apps as well.

    Adobe Dreamweaver

    Yes, that is plural Debugging Environments. Due to the cross-platform natureand PhoneGaps leveraging of native web views for each platform, debuggingPhoneGap applications can sometimes be tricky. Here are some tips that will makethis significantly easier.

    DEBUGGING ENVIRONMENTS

    8 of 16

  • 8/13/2019 Appliness #11 February 2013

    56/140

    UTORIALSMY WORKFLOW FOR DEVELOPING PHONEGAP APPLICATIONS

    THE PHONEGAP EMULATOR

    The PhoneGap Emulator is my primary development/debugging tool for allPhoneGap apps. It is a browser-based emulator leveraging the Google Chrome

    browser and the Ripple Emulation Environment. The PhoneGap Emulator runsinside of Google Chrome, and provides emulation of PhoneGaps core APIs. Sinceit is built on top of Chrome, it enables you to leverage Chromes Developer Tools,which in my opinion are second to none for web/application development. This isa highly-productive developer environment.

    PhoneGap Emulator in Google Chrome

    Heres why I like the PhoneGap/Ripple/Google Chrome development environment:

    First, this combination enables you to emulate most core PhoneGap APIs withoutleaving the desktop environment. It enables you to test various APIs includinggeolocation (with simulated locations), device events (deviceready, back, etc),sensor events (accelerometer, compass), and even lets you test with different

    9 of 16

  • 8/13/2019 Appliness #11 February 2013

    57/140

    UTORIALSMY WORKFLOW FOR DEVELOPING PHONEGAP APPLICATIONS

    device aspect ratios all without having to push anything to an actual device. Thissaves a lot of time in development iterations. You can read about the supportedRipple emulator features here.

    Second, Chromes Developer Tools are awesome. Here are just a few things that

    you can do while developing/debugging your app, live within the emulationenvironment:

    1. Alter DOM and CSS at runtime via the elements panel.2. Analyze all resources consumed by your app, via the resources panel. This includes

    all scripts, images, html files, cookies, etc it even includes insight into any localdata stored via PhoneGaps local storage database (WebSQL implementation).

    3.View/query all local databases within your app. You can write your own queriesto view/alter data in the WebSQL database. Thanks to Ray for sharing this, its

    not immediately intuitive.

    Debugging Local Storage Databases in Chrome with SQL

    4. Analyze network requests/utilization via the network panel.5. Debug JavaScript with the Scripts/Sources Panel. You can set breakpoints in JS

    execution, inspect & alter values in JS objects in-memory, and view details andline numbers for any exceptions that occur.

    6. Monitor function execution time, memory consumption, event listeners, andframe rendering time via the timeline panel.

    10 of 16

  • 8/13/2019 Appliness #11 February 2013

    58/140

    UTORIALSMY WORKFLOW FOR DEVELOPING PHONEGAP APPLICATIONS

    Chrome Timeline Panel

    7. Profile CPU/Memory usage via the profiles panel.8. Use the console to monitor console.log() statements, inspect properties of

    objects in memory, or execute arbitrary JavaScript whenever you want.

    The PhoneGap Emulator enables developers to be extremely productive withdevelopment, however I cannot emphasize enough that on-device testing is

    critical for having a successful app. On-device testing can expose performanceproblems or browser rendering variances that you may not notice in the emulatorenvironment.

    ON-DEVICE REMOTE DEBUGGING

    As I mentioned above, on-device testing is critical for successful applications. iOSand BlackBerry have an advantage over other platforms b/c the latest developertools allow you to remotely debug content live on a device.

    Since the release of iOS 6, you can debug content in the iOS simulator using SafarisDeveloper Tools. Safaris developer tools give you many of the same debuggingcapabilities that I mentioned above for Chrome.

    11 of 16

  • 8/13/2019 Appliness #11 February 2013

    59/140

    UTORIALSMY WORKFLOW FOR DEVELOPING PHONEGAP APPLICATIONS

    To debug an app running in the iOS simulator, just go to Safaris Develop menu,select iPhone Simulator, then select your apps index.html file.

    Connect Remote Debugging

    Youll end up with a full remote debugging experience, just like if you were debugginginside the Safari browser, complete with JS breakpoints, DOM inspection, etc

    Remote Debug iOS Simulator with Safari

    12 of 16

  • 8/13/2019 Appliness #11 February 2013

    60/140

    UTORIALSMY WORKFLOW FOR DEVELOPING PHONEGAP APPLICATIONS

    The process to remotely connect to a live app running on an external iOS deviceis very similar. Just follow the instructions here, under the Remote Debuggingsection, and you will be up and running very quickly.

    The latest BlackBerry devices also have the same remote debugging capability

    (since it is all actually based on the webkit engine). You can view detailed instructionshow to remotely debug PhoneGap apps on BlackBerry devices here.

    REMOTE DEBUGGING WITH WEINRE

    Not every platform supports live remote debugging, especially older versions.Weinre (pronounced winery) is a remote web inspector that allows you to inspect/edit DOM and CSS elements on remote devices. Basically, you include someJavaScript in your app, and it communicates back to a server that will tell you

    whats happening inside of the app running on the mobile device. It wont giveyou full debugging capabilities like JS breakpoints and memory inspection, but itsbetter than nothing. You can use Weinre by setting up your own instance, or byleveraging debug.phonegap.com.

    Weinre for On-Device Debugging

    13 of 16

  • 8/13/2019 Appliness #11 February 2013

    61/140

    UTORIALSMY WORKFLOW FOR DEVELOPING PHONEGAP APPLICATIONS

    WHEN ALL ELSE FAILS

    If youre still debugging your apps, and the solutions mentioned above dont work,you can always resort to plain-old alert() statements to pop up debug messages,or use console.log() statements to write to system logs.

    On Android, all console.log(...); messages will appear as printouts in the command-line tool logcat, which is bundled with the Android SDK and integrated into theAndroid Eclipse plugin.

    On BlackBerry, all console.log(...); are printed to the BlackBerrys Event Log. TheEvent Log can be accessed by pressing ALT + LGLG.

    On iOS, all console.log(...); are output to the Xcode Debug Area console.

    Read more about debugging PhoneGap apps here.

    The PhoneGap getting started guides will point you to the right direction forgetting started with a particular platform. If you are just targeting iOS, you can use

    Xcode for building. If you are just targeting Android, you can use Eclipse, etc Itis all very easy to get up and running.

    However, this process gets much more complicated when targeting multipleplatforms at once. When I have to do this, PhoneGap Buildbecomes really, reallyhandy.

    BUILDING PHONEGAP APPS

    14 of 16

  • 8/13/2019 Appliness #11 February 2013

    62/140

  • 8/13/2019 Appliness #11 February 2013

    63/140

    UTORIALSMY WORKFLOW FOR DEVELOPING PHONEGAP APPLICATIONS

    If you are interested in UI frameworks, take a look at these:

    Twitter Bootstrap Zurb Foundation Sencha Touch

    Kendo UI jQuery Mobile Enjyo.js app-UI Moobile Chocolate Chip UI Dojo Mobile

    If you are interested in architectural patterns, take a look at these.

    Backbone.js Knockout.js Angular.js Ember.js Ext.js

    There are lots, and lots, and lots more options out in the HTML/JS developmentworld Im not even taking into account JavaScript generating tools and languageslike CoffeeScript, TypeScript, or others

    Hopefully this helps get you on the right track.

    Enjoy!

    Andrew TriceTechnical Evangelist

    at Adobe

    HISBLOG

    TWITTER

    SHARE

    GITHUB

  • 8/13/2019 Appliness #11 February 2013

    64/140

    appliness TUTORIALS JAVASCRIPT BOOKMARK / SHARE / TO

    Android Push Notificationswith PhoneGap.

    by HollySchinsky

  • 8/13/2019 Appliness #11 February 2013

    65/140

    UTORIALSANDROID PUSH NOTIFICATIONS WITH PHONEGAP

    by HollySchinsky

    2 of 12

    My last postcovered push notifications with PhoneGap on Apple devices, but I alsowanted to cover push notifications with PhoneGap on Android for those developingcross platform applications. I found that I was able to get my notifications workingmuch faster on Android comparatively.

    Android push notifications are available via the Google Cloud Messaging GCMservice(similar to Apples Push Notification Service). Previously they were supported throughC2DM(Cloud to Device Messaging framework)but that API has since been deprecated and theGoogle Cloud Messaging services addsenhancements above and beyond what C2DMoffered. Theres a Cordova/PhoneGap pluginavailable to aid in working with the GoogleCloud Messaging service. The message size

    allotment for the GCM payload is 4kb (Stringdata only), noticeably bigger than the ApplePush Notification requirements of 256 bytes.Theres an article about the types of messages

    that can be sent in detail here. Also, I suggest you look over the documentation forusing this service in general here when building your application, there are a lot ofdetails I will not cover in this post. Some points I wanted to highlight from that articleare:

    GCM makes no guarantees about delivery or the order of messages. An Android application on an Android device doesnt need to be running to receive

    messages. The system will wake up the Android application via Intent broadcast whenthe message arrives, as long as the application is set up with the proper broadcastreceiver and permissions.

    It does not provide any built-in user interface or other handling for message data.GCM simply passes raw message data received straight to the Android application,which has full control of how to handle it. For example, the application might post anotification, display a custom user interface, or silently sync data.

    GOOGLE CLOUD MESSAGING

    I was able to get mynotifications working much

    faster on Android...

  • 8/13/2019 Appliness #11 February 2013

    66/140

    UTORIALSANDROID PUSH NOTIFICATIONS WITH PHONEGAP

    The steps for setting up push notifications in your Android application are:

    1. Create a new Android Cordova project either via the command line tools or

    Eclipse(command line recommended)2. Download the GCM Cordova Plugin3. Follow the steps in the plugins Readme

    Dont forget to setup your Google Cloud Messaging Account as noted in thereadme and note your project id located in the URL. For instance the number inbold below is the id you need to send in the register()function:

    https://code.google.com/apis/console/?pli=1#project:824841663942

    Dont forget to change the following to use your GCM project id (from thestep above)

    window.GCM.register(your_sender_id, GCM_Event, GCM_Success, GCM_Fail );

    becomes

    window.GCM.register(824841663942, GCM_Event, GCM_Success, GCM_Fail );

    Add code handling for the actions to take when the application receives a messagewhile open or not (ie: display a popup alert, status bar notification etc).

    Note:The plugin handles registering with GCM and has methods for receiving amessage, however it does not actually provide the notification code itself, this issomething you need to add. Read on further for how to add native code to producea status bar notification.

    If you need more information about GCM project creation, specific steps can befound here.

    The plugin includes a sample project already setup to register for push notifications (includesthe AndroidManifest.xml changes and plugin configuration already), all you have to do is editthe CORDOVA_GCM_script.js file to use your GCM sender/project id in the register functionand you can run it immediately or use this project as a reference while making the changes toyour own.

    STEPS

    3 of 12

  • 8/13/2019 Appliness #11 February 2013

    67/140

    UTORIALSANDROID PUSH NOTIFICATIONS WITH PHONEGAP

    If you prefer to use Eclipse for your editing, you can simply import your existingAndroid project that you just created above (or the sample included in the plugin)and start working from there. Choose File | New | Project, then you will see thefollowing dialog, where you will select Android Project from Existing Code as

    follows:

    4 of 12

  • 8/13/2019 Appliness #11 February 2013

    68/140

    UTORIALSANDROID PUSH NOTIFICATIONS WITH PHONEGAP

    When you run the sample code from the plugin, it will automatically try to registeryour device. If registration is successful, you should see a message containing theregistration token id as I circled below in the screenshot of mine running on my

    Galaxy Tablet:

    You should also see the following trace in your console:

    10-24 18:24:20.720: V/GCMReceiver:onRegistered(21989): Registration ID arrived!10-24 18:24:20.730: V/GCMReceiver:onRegisterd(21989): {regid:APA91bFobAwM7P3Okxy2al8RI12VcJFUS-giXWTOoWXIObtSPOE1h7FuH1VPLBPgshDI_Fp7aIYVET-ssvGUErlWYA0cKPGhoXT1daqyDsEfem9ZtgZNRhQFv7kLCIVSigYlpMluToPiSHSsFSEdtCDfKoOZqNPsfg, event:registered}10-24 18:24:20.730: V/GCMPlugin:sendJavascript(21989): javascript:GCM_Event({regid:APA91bFobAwM7P3Okxy2al8RI12VcJFUS-giXWTOoWXIObtSPOE1h7FuH1VPLBPgshDI_

    Fp7aIYVET-ssvGUErlWYA0cKPGhoXT1daqyDsEfem9ZtgZNRhQFv7kLCIVSigYlpMluToPiSHSsFSEdtCDfKoOZqNPsfg,event:registered})

    RUNNING THE SAMPLE APPLICATION

    5 of 12

  • 8/13/2019 Appliness #11 February 2013

    69/140

    UTORIALSANDROID PUSH NOTIFICATIONS WITH PHONEGAP

    Once you have obtained a registration id as above, you can write server code (seethe section below on using Node.JS code to send a message to your application)or use a service like Urban Airshipor PushWooshto start sending notifications.When a message is received, you will see additional text displayed as shown in thescreenshot below:

    At this point though, the plugin does not contain anything more to actually show astatus bar notification or otherwise notify you. The next section covers how youcan add some additional code to it for showing a status bar notification when themessage is received.

    6 of 12

  • 8/13/2019 Appliness #11 February 2013

    70/140

    UTORIALSANDROID PUSH NOTIFICATIONS WITH PHONEGAP

    Since the plugin simply receives the message (whether running or not) but doesntdo anything with it from there, you have various choices for what you could do withit. One common thing is to show a message in the native status bar. Note that on iOS

    the process is different and the notification is automatically shown, but on Androidyou have to explicitly code for it. You could use the Cordova StatusBarNotificationpluginalong with this one, or if you want a faster solution, you could simply addthe following native Java code into your GCMIntentService.java onMessage()function:

    String message = extras.getString(message);String title = extras.getString(title);Notification notif = new Notification(android.R.drawable.btn_star_big_on,message, System.currentTimeMillis() );notif.flags = Notification.FLAG_AUTO_CANCEL;notif.defaults |= Notification.DEFAULT_SOUND;notif.defaults |= Notification.DEFAULT_VIBRATE;Intent notificationIntent = new Intent(context, TestSampleApp.class);notificationIntent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);PendingIntent contentIntent = PendingIntent.getActivity(context, 0,notificationIntent, 0);notif.setLatestEventInfo(context, title, message, contentIntent);

    String ns = Context.NOTIFICATION_SERVICE;NotificationManager mNotificationManager = (NotificationManager) context.getSystemService(ns);mNotificationManager.notify(1, notif);

    Also, dont forget to add these imports at the top of the file to support the abovecode:

    import android.app.Notification;import android.app.NotificationManager;

    import android.app.PendingIntent;

    Be sure to replace YourActivityClassName.class with the name of your stub class that extendsDroidGap. For instance, in the sample project it is called MainActivity.

    STATUS BAR NOTIFICATION

    7 of 12

  • 8/13/2019 Appliness #11 February 2013

    71/140

    UTORIALSANDROID PUSH NOTIFICATIONS WITH PHONEGAP

    The above code sets the notification to include a star icon, vibration and the defaultsound. An example of it running on my Android Galaxy Tablet is shown below(circled in red).

    When you click on the notification, the app will open and look like the following,showing that a message was in fact received:

    Status bar notifications will be displayed differently depending on the type of device. SomeAndroid devices will show them at the top versus at the bottom as shown in my screenshots

    8 of 12

  • 8/13/2019 Appliness #11 February 2013

    72/140

    UTORIALSANDROID PUSH NOTIFICATIONS WITH PHONEGAP

    Theres a Node.jslibrary for sending notifications through Google Cloud Messagingas there was for Apples Push Notification Service as I showed in my last post.Its called node-gcm, and below is the code I used to send my device a message

    (keys changed ). In the Senderparameter you need to specify the API key thatGoogle gave you when you registered for the Google Cloud Messaging service.

    You received two API keys, a browser and server key, either should work here, butif one does not, try the other ! You also need to specify the token returned to yourapplication when you registered using the plugin above. This is the registration idthat was printed to the screen and console when you ran the application and calledthe GCM registerfunction.

    vargcm = require(node-gcm);

    varmessage = new gcm.Message();varsender = new gcm.Sender(AIzaSyCDx8v9R0fMsAsjoAffF-P3FCFWXlvwKgL);varregistrationIds = [];message.addData(title,My Game);message.addData(message,Your turn!!!!);message.addData(msgcnt,1);message.collapseKey = demo;message.delayWhileIdle = true;message.timeToLive = 3;

    // At least one token is required - each app will register a different tokenregistrationIds.push(APA91bFobAwN7P3Okxy2al8RI12VcJFUS-giXWTOoWXIObtSPOE1h7FuH1VPLBPgshDI_Fp7aIYVET-ssvGUErlWYA0cKPGhoXT1daqyDsEfem9ZtgZNRhQFv7kLCIVSigYlpMluToPiSHSsFSEdtCDfKoOZqNPgfs);/*** Parameters: message-literal, registrationIds-array, No. of retries,callback-function*/

    sender.send(message, registrationIds, 4, function(result) { console.log(result);});/** Use the following line if you want to send the message without retriessender.sendNoRetry(message, registrationIds, function(result) { console.log(result); });**/

    You need to set the name of the title and message keys explicitly to title and message as theapplication plugin code is looking for that in GCMIntentService.java:

    SENDING A MESSAGE WITH NODE-GCM

    9 of 12

  • 8/13/2019 Appliness #11 February 2013

    73/140

    UTORIALSANDROID PUSH NOTIFICATIONS WITH PHONEGAP

    Bundle extras = intent.getExtras(); if (extras != null) { try { String title = extras.getString(title); String message = extras.getString(message);

    .... } }

    COLLAPSE KEYAccording to the Android developer documentation, when you define a collapsekey, it will only deliver the last one with a given collapse key, therefore saving theuser from becoming over-notified such as in the case of sports scores for example.

    10 of 12

  • 8/13/2019 Appliness #11 February 2013

    74/140

    UTORIALSANDROID PUSH NOTIFICATIONS WITH PHONEGAP

    Also, note that these status bar notifications will be shown in the expanded list (ifnot dismissed yet) such as in the following:

    11 of 12

  • 8/13/2019 Appliness #11 February 2013

    75/140

    UTORIALSANDROID PUSH NOTIFICATIONS WITH PHONEGAP

    Lastly, I wanted to point out that if you are googling about Cordova pushnotification plugins for Android, you may also come across another one here. Thisone is supposed to be more specific to using notifications from PushWoosh, whichI will cover in a future post with a sample. The plugin API more closely resembles

    the iOS Cordova PushNotification plugin, and interestingly enough still workedin receiving push notifications from my Node.js service completely outside of thePushWoosh service when I tested it (and I did not have to add the native Java codeshown above to show the status bar notification) so I wanted people to be awareof it in case they wanted to try this plugin as well.

    OTHER PLUGIN OPTIONS

    Holly SchinskyDeveloper Evangelist

    HERBLOG

    TWITTER

    SHARE

    GITHUB

  • 8/13/2019 Appliness #11 February 2013

    76/140

    appliness INTERVIEW MIKO HEVERY BOOKMARK / SHARE / TO

  • 8/13/2019 Appliness #11 February 2013

    77/140

    appliness INTERVIEW DENISE JACOBS BOOKMARK / SHARE / TO

    INTERVIEWMIKOHEVERY

    by Maile Valentinephotos by LucieXYZ Photography

    Misko Hevery started coding at 8 after his father boughtthe first computer in their tiny village in Slovakia. From

    his early days of BASIC programming to making com-puter chips before moving on to building web applications, Miskohas developed a passion for making developers productive. Hispath eventually lead him to create AngularJS, the current successof which seems to be the result of a bet. Is Angular destined tobecome HTML6? Time will tell

  • 8/13/2019 Appliness #11 February 2013

    78/140

    TERVIEWMIKO HEVERY

    3 of 14

    APPLINESS: Hello Misko! Thankyou very much for your time, weare honored to have you featuredin Appliness. Can you tell us a bitabout yourself?

    Miko Hevery: Thanks for having me!I work for Google and my passion ismake developers productive. I want tohelp build the next awesome apps, notnecessarily directly, but indirectly byelevating the software developmentdiscipline. For many years I havefocused both internally in Google aswell as in Open Source community in

    sharing my passion for writing bettersoftware through testing.

    About three years ago, I have becomepassionate about making it easy tobuild large scale interactive AJAX styleapplications on the web. I am a firmbeliever, that unless the easy stuff iseasy, the complex stuff is impossible.

    Before Google, I have worked inAdobe, Sun, and even Intel. I say evenIntel, since Intel builds chips not web-applications, and I am a hardwareengineer by training, which hasswitched to software and then to web-applications.

    When did you start coding? Whatpeaked your interest in development?

    It all started when my dad in 1984read in the magazine about personal

    computers and he had to get one. Butback then we lived in a tiny village inSlovakia, and we must have been thefirst family to own a personal computerin the county, if not the first. I becameenamored with programming, startingwith BASIC as my first programminglanguage at the age of eight, and Ihave not stopped coding since.

  • 8/13/2019 Appliness #11 February 2013

    79/140

    MIKO HEVERYABOUTANGULAR

    Can you tell us a bit about Angularand how you came to develop it, itshistory?

    Every web-application is really justonce complex marshaling problem.We marshal data from the DB, throughthe HTTP into the heap and to the

    DOM for the user to read, and then

    we do it all again in reverse order. Atfirst this is fun, but after you build fewapplications, you very quickly get tiredof marshaling your data through theselayers, and I wanted to do somethingabout it.

    Specifically, I wanted to make web-

    apps so easy that anyone could do it.4 of 14

    TERVIEWMIKO HEVERY

  • 8/13/2019 Appliness #11 February 2013

    80/140

    TERVIEWMIKO HEVERY

    5 of 14

    I set my eye on web-designers, and Iwondered if I could bring the DB to theHTML, such that any static web-serverserving your local mom and pop pizzashop could throw in some HTML sugarand have a web-site which could send

    email, persist form data, all withouthaving to maintain or understand anybackend technologies. The result wasa service which provided a librarywhich then allowed the web-designerto turn any static page into a dynamicone.

    The turning point came when I was

    working on internal Google project.After 6 months of building a GWTapplication with three engineers, wewere getting frustrated with the lack ofgood feature velocity. I bragged that Icould redo this app in Angular in twoweeks, and my team called me on it. Ilost the bet, because it took me threeweeks, but after our codebase shrunkto one 17th the original size peoplepaid attention. At this point Angularwas not what it is today, and theapplication build in Angular was moreor less one big hack, but it showed whatis possible with declarative approach.

    From that moment on, my job was to

    turn Angular into a real framework.At first we used it for our internalGoogle application, but soon otherteams started to notice. Specificallythe Doubleclick for Advertisers team,which was just in the midst of doinga rewrite, became our toughestcustomer, building a large scaleenterprise applications on top of it.

    Three more software engineers andtwo more years later and we hadAngular v1.0 to share with the world.

    What problem did AngularJS solvefor developers?

    HTML and browsers are awesome forserving static documents. Turning staticpages into dynamic ones is possiblewith JavaScript, but the fact that theplatform was not originally designedto serve dynamic applications showspainfully every step of the way.

    Angular increases the abstractionlevel of the browser to make it moresuitable for building dynamic web-applications. It does this not bycreating new syntax, but by teachingthe old browsers new tricks. Angularis instantly familiar to web-developerssince it just HTML with features whichmake building dynamic pages easy.

    Angular provides data binding,components, dependency injection,and a testing for the application.

    How is it unique from otherframeworks?

    Most developers see a complexproblem and they write a function forit, and then tell everyone to use it. I dothings differently. I dont want to hidethe problem behind a function, I wantthe problem to go away. I dont wantothers to run into the problem andsay, I wonder if anyone has solvedthis and put it behind a function that

    I can use. I want the problem to be

  • 8/13/2019 Appliness #11 February 2013

    81/140

    TERVIEWMIKO HEVERY

    6 of 14

    leveled with the ground, so that whenthe next developer passes through,there is nothing to snag on. I want thedeveloper to pass by without evenrealizing that there used to be nastyproblem hiding here, the developer

    should be blissfully ignorant. Whenyou think this way, the result is not alibrary which has functions for commonproblems, the result is a browserwith fever-sharp edges.When you develop inAngular, you aredeveloping in abetter