We’ll use the awesome GitHub.com to host our static website and create it using an existing template. Github hosts your website code history publicly and you benefit, among other things, from code versionning and free, high-quality hosting (cdn, ddos protection…).

WARN Files stored on Github are public to anyone (except if you buy a private repo), so don’t store anything sensible here.

What is a “static” website ?

For small websites, CMS solutions like WordPress and equivalents are largely overkill and require some technical setup and mandatory maintenance mostly due to security patches and unattended upgrades.

Nowadays, it is possible to create awesome websites in a server-less way, using only client-side technologies. This mean you can host your website anywhere without any configuration, as all the code executes is only in the final user browser (HTML, Javascript and CSS), and this has several advantages :

simple

no maintenance

no hacking

better performance

less is more

simple is beautiful

Any serious business now offers an API that you can integrate in some way your static website if you need so this static approach has NO LIMIT.

Javascript prototypal inheritance can be confusing at first if you come from classical OOP languages, due to Javascript versatility, and the variety of JavascriptOOPpatternsavailable. Combined with the new service and factory concepts introduced in AngularJS, implementing OOP in your applications can lead to serious headaches, so i’ll try to show you some solutions here.

Once your app grow and your services multiply, you’ll quickly feel the need to reuse your code, and to split it in small modules to be able to separate concerns and setup some serious unit testing.

In this post, i’ll show how to create a base AngularJS service, based on the Github API, that we’ll be able to extend and reuse in different scenarios. We’ll also leverage the power of promises chaining to extend the server responses and add additional data before returning the final result.

Something important to note here is that factories are useful to define our classes that you can instantiate many times using the new keyword, while services always create singletons.

Create our base service

Our first service will be responsible of fetching Github basic user data and return the result. We’ll use a factory instead of a service, which will make it easier to instantiate many versions of the service in our application.

12345678910111213141516171819202122232425262728293031

app.factory('SimpleGithubUser',function($http){varapiUrl='https://api.github.com/';// instantiate our initial objectvarSimpleGithubUser=function(username){this.username=username;this.profile=null;};// define the getProfile method which will fetch data// from GH API and *returns* a promiseSimpleGithubUser.prototype.getProfile=function(){// Generally, javascript callbacks, like here the $http.get callback,// change the value of the "this" variable inside it// so we need to keep a reference to the current instance "this" :varself=this;return$http.get(apiUrl+'users/'+this.username).then(function(response){// when we get the results we store the data in user.profileself.profile=response.data// promises success should always return something in order to allow chainingreturnresponse;});};returnSimpleGithubUser;})

So we can now easily inject our factory anywhere and use it like this :

123456789

// we first inject our factoryapp.controller('MyCtrl',function(SimpleGithubUser){// instantiate a new uservaruser=newSimpleGithubUser('substack');// fetch data and publish on scopeuser.getProfile().then(function(){$scope.userLogin=user.profile.login;})});

Extending the base service

Now we’d like to attach some additional data to our users. Instead of modiying the original factory, or even worse, duplicate it, we can create another factory that extends the original one, just by using the regular javascript prototypal inheritance. We’ll override some methods and use promises chaining to deliver the final data only when all the subsequent requests have been completed.

This has the advantage of encapsulating the logic inside the new service, making it easily testable while keeping your controllers light.

In this example we’ll add some data from the Github events API and attach it to the user profile before returning the final result.

// we define a new factory and inject our original service so we can extend it properlyapp.factory('AdvancedGithubUser',function($http,SimpleGithubUser){varapiUrl='https://api.github.com/';// create our new custom object that reuse the original object constructorvarAdvancedGithubUser=function(){SimpleGithubUser.apply(this,arguments);};// reuse the original object prototypeAdvancedGithubUser.prototype=newSimpleGithubUser();// define a new internal private method for this objectfunctiongetUserEvents(){varself=this;return$http.get(apiUrl+'users/'+this.username+'/events').then(function(response){// attach the events API result to our user profileself.profile.events=response.data;// promises should always return a resultreturnresponse;});}// Now let's override our original getProfile methodAdvancedGithubUser.prototype.getProfile=function(){varself=this;// we first call the original getProfile method (aka super method)varoriginalGetProfile=SimpleGithubUser.prototype.getProfile.apply(this,arguments);// we use promises chaining to add additional datareturnoriginalGetProfile.then(function(){// before returning the result,// call our new private method and bind "this" to "self"// we need to do this because the method is not part of the prototypereturngetUserEvents.call(self);});};returnAdvancedGithubUser;});

Usage is exactly the same, except the service added the events data for us :

123456789

// we first inject our factoryapp.controller('MyCtrl',function(AdvancedGithubUser){// instantiate a new uservaruser=newAdvancedGithubUser('substack');// fetch data and publish on scopeuser.getProfile().then(function(){$scope.userEvents=user.profile.events;})});

Create a service instance

Now that you have some solid factories, you can also instantiate some app-wide services that expose pre-configured instances.

Final result

In this article, i’ll detail the process to unit test the stepper directive we’ve created in the last week custom component creation article. Next week, i’ll cover how to distribute your component via GitHub and Bower.

Unit testing is the art of testing individually every smallest part of your code, which are the foundations of your apps sanity. Once correctly tested, these parts assembled together will also play nicely, as their behaviour has already been validated independently.

Another usage is, when you get a new bug report, you add the revelant test that demo the bug, fix it in your code so the test will pass, then keep it there as a proof of reliability.

Among AngularJS best friends there is the KarmaJS test runner (A nodeJS server to launch the tests in browsers and reports the results) and the Jasmine behaviour-driven testing framework (the language to define your tests and expectations). We’ll use the grunt-karma task to integrate karma in our classic yet awesome grunt workflow and launch the tests in our browsers. Note that karma can run the tests in remote cloud browsers, for example via SauceLabs or BrowserStack.

AngularJS is made from ground-up for testing, so make yourself a favor, start NOW :)

Glossary

There are some terms that may need clarification before we go further :

spec : the specifications of something you want to test, consisting one or many tests suites. should cover all the expected behaviour.

test suite : This is a group of tests; defined within a describe block in Jasmine. blocks can be nested as much as needed.

test : Test instructions, that ends with one or more expectations; defined within a it block in Jasmine.

actual : this is the value you test in your expectation.

expected value : this is the value you test the actual value against.

matcher : A function that compares the actual and the expected values and returns a boolean success result to Jasmine. eg : toEqual, toBeGreatherThan, toHaveBeenCalledWith… you can even define your owns.

expectation : Use the expect function to test a value, called the actual. It is chained with a matcher function, which takes the expected value.

mock : a stubbed service that replace a real one at runtime with fake data/methods that you can control during your tests.

Code our directive unit tests

Below you can see an extract of our angular-stepper component test suite (angular-stepper.spec.js), and here’s the full spec. Our tests for such a component are quite simple, no need for mocks here. The only tricky thing is that we wrap our directive inside a form to be able to test that it plays well with ngModelController and updates form validity correctly.

// the describe keyword is used to define a test suite (group of tests)describe('rnStepper directive',function(){// we declare some global vars to be used in the testsvarelm,// our directive jqLite elementscope;// the scope where our directive is inserted// load the modules we want to testbeforeEach(module('revolunet.stepper'));// before each test, creates a new fresh scope// the inject function interest is to make use of the angularJS// dependency injection to get some other services in our test// here we need $rootScope to create a new scopebeforeEach(inject(function($rootScope,$compile){scope=$rootScope.$new();scope.testModel=42;}));functioncompileDirective(tpl){// function to compile a fresh directive with the given template, or a default one// compile the tpl with the $rootScope created above// wrap our directive inside a form to be able to test// that our form integration works well (via ngModelController)// our directive instance is then put in the global 'elm' variable for further testsif(!tpl)tpl='<div rn-stepper ng-model="testModel"></div></form>';tpl='<form name="form">'+tpl+'</tpl>';// inject allows you to use AngularJS dependency injection// to retrieve and use other servicesinject(function($compile){varform=$compile(tpl)(scope);elm=form.find('div');});// $digest is necessary to finalize the directive generationscope.$digest();}describe('initialisation',function(){// before each test in this block, generates a fresh directivebeforeEach(function(){compileDirective();});// a single test example, check the produced DOMit('should produce 2 buttons and a div',function(){expect(elm.find('button').length).toEqual(2);expect(elm.find('div').length).toEqual(1);});it('should check validity on init',function(){expect(scope.form.$valid).toBeTruthy();});});it('should update form validity initialy',function(){// test with a min attribute that is out of bounds// first set the min valuescope.testMin=45;// then produce our directive using itcompileDirective('<div rn-stepper min="testMin" ng-model="testModel"></div>');// this should impact the form validityexpect(scope.form.$valid).toBeFalsy();});it('decrease button should be disabled when min reached',function(){// test the initial button statuscompileDirective('<div rn-stepper min="40" ng-model="testModel"></div>');expect(elm.find('button').attr('disabled')).not.toBeDefined();// update the scope model valuescope.testModel=40;// force model change propagationscope.$digest();// validate it has updated the button statusexpect(elm.find('button').attr('disabled')).toEqual('disabled');});// and many others...});

Some notes :

A directive needs to be compiled in a given scope to be tested

A non-isolated scope can be acceded via element.scope()

An isolated scope can be acceded via element.isolateScope()

Why to we have to call scope.$digest() when we change a model value in the tests ?

In a real angular app, the $digest is automatically triggered by the framework in reaction to various events (clicks, inputs, requests…). There’s no such user-based events during the automated tests so we just need to force the $digest. (the $digest is what update all the bindings).

Bonus #1: real time tests

Thanks to grunt, we can make the tests run when the source changes and be alerted in real time.

If you want the tests to be run on each code change, just add a section to your watch task :

1234

js:{files:['src/*.js'],tasks:['karma:unit:run','build']},

You could update your default grunt task like this

1

grunt.registerTask('default',['karma:unit','connect','watch']);

Now, just run grunt and you’ll get real-time tests and a builtin webserver :)

Bonus #2: add code coverage reporting

As developers, we love solid metrics; and we also love continous improvements. “coverage” refers to the code coverage of your test suite; It gives you metrics and detailed info to increase your code coverage without pain.

Here’s a sample coverage HTML report :

We can see, for each folder and file, how much code is covered by our test suite. And this is updated in real-time thanks to grunt+karma integration. For each file, we can see line by line which blocks stays untested, which makes writing the remaining tests more straightforward.

Its really easy to integrate this in our karma+grunt setup. Karma has a “plugin” system that allows you to plug the fantastic Istanbul code coverage tool so we just need to configure the karma-unit.js file and we’re done :)

Add coverage to karma

12

# add the necessary node_modulesnpm install karma-coverage --save-dev

now update the karma config file with these new settings :

1234567891011121314

// here we specify which of the files we want to appear in the coverage reportpreprocessors:{'src/angular-stepper.js':['coverage']},// add the coverage pluginplugins:['karma-jasmine','karma-firefox-launcher','karma-chrome-launcher','karma-coverage'],// add coverage to reportersreporters:['dots','coverage'],// tell karma how you want the coverage resultscoverageReporter:{type:'html',// where to store the reportdir:'coverage/'}

One of the beauty of the AngularJS framework is its ability to isolate complexity with services and directives; This is perfect for segmenting our code, create very testable components, and make them reusable. A directive, which is an anticipation of the future web components, is a piece of isolated javascript, HTML and CSS that encapsulate a specific behaviour and that you can easily reuse in various apps. Once created, a directive is simply invoked by adding it to the DOM via a HTML tag (<accordion></accordion>, or a custom attribute <div accordion></div>, or a CSS class <div class="accordion"></div> (and even as HTML comment).

In this tutorial we’ll go through the creation of a custom stepper directive that can be used as a reusable input component in your applications. We’ll cover the classic directive creation but also the input validation, and the use of the ngModelController, that will allow a seamless integration with any form, leveraging the existing AngularJS forms superpowers. The next part will cover the test suites with Jasmine and KarmaJS, and the publication and distribution of our widget with GitHub and bower.

For this example we’ll build a custom numeric input widget, named “rn-stepper”. We’ll use the last AngularJS 1.2 that brings some important fixes to the private scopes management (capital point for reusable components). The full widget code is available on github as a reusable component and you can see the final result here :

Markup generation

The first step is to create a naïve directive that build our markup, and renders correctly. We just declare the directive name, and template to use.

12345678910111213

// we declare a module name for our projet, and its dependencies (none)angular.module('revolunet.stepper',[])// declare our naïve directive.directive('rnStepper',function(){return{// can be used as attribute or elementrestrict:'AE',// which markup this directive generatestemplate:'<button>-</button>'+'<div>0</div>'+'<button>+</button>'};});

Add internal behaviour

Now we need to add behaviour and internal variables to our custom component. We’ll declare a “private scope” that will hold internal variables and functions, and add the link function to our directive, which is responsible of initialising the component behaviour just after the markup has been inserted in the final page.

Here’s the updated directive code :

12345678910111213141516171819202122

.directive('rnStepper',function(){return{restrict:'AE',// declare the directive scope as private (and empty)scope:{},// add behaviour to our buttons and use a variable valuetemplate:'<button ng-click="decrement()">-</button>'+'<div></div>'+'<button ng-click="increment()">+</button>',// this function is called on each rn-stepper instance initialisation// we just declare what we need in the above templatelink:function(scope,iElement,iAttrs){scope.value=0;scope.increment=function(){scope.value++;}scope.decrement=function(){scope.value--;}}};});

We now have a functionnal component with an isolated code and template.

Communicate with the external world

Our component works great but it would be more useful if it could control a real public variable, known as a ngModel in AngularJS.

Let’s add a databinding between our component internal value and the outer world (our application).

We just need to update our scope declaration like this :

123

scope:{value:'=ngModel'}

This will automagically bind our internal value variable to the external one declared in the ngModel attribute. The = means “double data-binding” which means if ngModel is updated externally then the internal value will be updated, and vice-versa.

Say my app expose a rating variable, we could now bind it to our component simply like this :

Make our component form-friendly

We now have a dynamic input that can manipulate arbitrary ngModel data. We need to modify a bit the code to make it play nice with the AngularJS forms. For example, AngularJS forms and input generally expose a $pristine and $dirty state which can be useful in many situation. To make the forms aware of our model changes from inside our component, we need to make use of the ngModelController.$render and ngModelController.$setViewValue API methods, which are available as soon as you “require” a ngModel on your directive.

The ngModelController.$render method is a method which you should override yourself in the directive and is responsible of updating the view; it will be called by the framework when the external ngModel changes. When the model changes, the framework executes the $formatters pipeline which is responsible of eventually converting the $modelValue raw value to a usable $viewValue.

For example, if your model is a real Date object, you’d want your input to display it as dd/mm/YY. The model-to-view conversion is made by the $formatters pipeline and the view-to-model by the $parsers pipeline. Once you get a ngModelController instance, you can easily insert new items in these pipelines.

The ngModelController.$setViewValue method should always be called when you want update a model from your directive (view). It takes care of calling the eventual $parsers pipeline. Then it applies the final value to the internal $modelValue, update the input $dirty state, update the optional parent form $dirty state and call any registered $viewChangeListeners. Here’s the full code for this function.

As pointed by a comment from @ThomasBelin4 below, we don’t need anymore to have a scope value variable, as we now have a reference to the original ngModelController which holds a reference to the viewValue.

.directive('rnStepper',function(){return{// restrict and template attributes are the same as before.// we don't need anymore to bind the value to the external ngModel// as we require its controller and thus can access it directlyscope:{},// the 'require' property says we need a ngModel attribute in the declaration.// this require makes a 4th argument available in the link function belowrequire:'ngModel',// the ngModelController attribute is an instance of an ngModelController// for our current ngModel.// if we had required multiple directives in the require attribute, this 4th// argument would give us an array of controllers.link:function(scope,iElement,iAttrs,ngModelController){// we can now use our ngModelController builtin methods// that do the heavy-lifting for us// when model change, update our view (just update the div content)ngModelController.$render=function(){iElement.find('div').text(ngModelController.$viewValue);};// update the model then the viewfunctionupdateModel(offset){// call $parsers pipeline then update $modelValuengModelController.$setViewValue(ngModelController.$viewValue+offset);// update the local viewngModelController.$render();}// update the value when user clicks the buttonsscope.decrement=function(){updateModel(-1);};scope.increment=function(){updateModel(+1);};}};});

Add min/max attributes

Now our component is form-friendly, so let’s as some builtin validation rules.

We could add optional min/max attributes to our component, which will handle the form validation by himself when they are present. These attributes will be data-bound so they can be updated at any time by the application (some other inputs in a form may impact the min/max here).

The ngModelController API gives us also a $setValidity method that can inform the parent forms about our component validity, and automatically add some handy CSS classes related to validity to out form and inputs.

We just need to call ngModelController.$setValidity('outOfBounds', false) to make our input, and thus parent forms invalids, and have ng-invalid and ng-invalid-out-of-bound CSS classes added to our forms and to our component.

Our stepper component is now full functionnal and integrates seamlessly in any form.

Prevent invalid input

Another nice-to-have feature would be to prevent the user from entering invalid data, which means disabling the buttons when the internal value reach the min/max limits. This could be achieved in two ways :

GOOD : automagically, using a builtin ng-disabled directive in our template, that will disable the buttons under some conditions.

The second option is much more Angular-ish and there are several ways to achieve this so let’s see how we can do.

We can add ng-disabled="isOverMin()" to our first button template and add a scope.isOverMin function that returns a boolean indicating if we should disable or not the given button. same with overMax that would check if the max has been reached or not.

What is CORS

In the internet AJAX early days (~2000) browsers vendors implemented a strict cross-domain communication policy that prevented javascript on a given page to communicate with third party domains. Many workarounds have been implemented since, like JSONP, which is only a ‘hack’ allowing cross-domain communication using javascirpt callbacks; Handy, but this prevents any other method than GET and forces the use of querystring to pass parameters.

With the RISE of internet APIs and decentralised services, having a way to communicate with 3rd party domain became critical; thus, the W3C defined the CORS protocol, acronym which stands for “Cross-Origin Resource Sharing” and allows different domains to communicate together, the same way Adobe Flash did it a long time before with the crossdomain.xml policy (remember?).

Now with CORS, the server defines which domains (applications) can communicate with him (or anyone). When CORS is enabled on the server, your javascript can communicate transparently using any HTTP method; For non-GET requests, the browser transparently make an initial OPTIONS request to check if the request is allowed or not, and then makes the real request.

CORS-enable your API

You can find the whole specs and various implementations at enable-cors.org.

Pain-free CORS for Apache servers

If you don’t want to change your code, we’ve crafted a small .htaccess for you that will force CORS on your API, without even touching your code. Just drop one of the implementations in your .htaccess and your API is magically CORS-enabled :)

Introduction

Topcoat.io is the new kid on the block of the CSS-only frameworks. It’s the first one that’s built for performance from the ground up, thanks to the constant performance tracking using Chrome telemetry, which makes it a tool of choice to build your mobile applications UI.It is also easy to theme and customize thanks to a smart CSS organisation and a powerful toolchain.

Topcoat has been built for the future, thanks to solid conventions and a cutting-edge javascript architecture, and more goodness :

All of this make it a powerful framework made to be extensible and performant.

Install Topcoat

Just download the latest release from github and extract it. The release contains the final CSS with dark and light themes for desktop and mobile, so you can use then directly; just add a link to the topcoat-mobile-light.min.css file in your app for example.

If you want to customize the themes or add new components, you need to run npm install from the topcoat folder. This will download all the widgets sources and local dependencies to your node_modules folder.

Some important things to notice :

Each component (button, list, checkbox…) has its own folder in the node_modules subfolder (so each one has its own npm repo). Each one also has its own gruntfile in case you want to build its css separately.

Most of components have a topcoat-[COMPONENT]-base folder with just enough CSS to completely reset the styling of the element, so other components can override it entirely. For example the default button hasn’t any default border or background and looks like a simple text block;

The topcoat-theme folder defines the 4 builtin Topcoat themes which are just a combination of variables that defines some variations of the components.

The main Gruntfile list the available themes and associated widgets using pattern globbing and this is from where the final CSS are built, including the given widgets.

Adding a custom theme

You can easily tweak the builtin themes by modifying the variables inside the topcoat-theme folder then run grunt to rebuild the final CSS. But its much better to add your own theme and leave the others untouched.

Let’s add a simple green theme :

copy the topcoat-theme/src/theme-topcoat-* file from the theme that matches the most your design, eg copy theme-topcoat-mobile-light.styl to theme-green.styl.

create a variables-green.styl with a bunch of variables that override the default ones (see the list of variables in the other variables-* files). For example :

add @import variables-green to your theme-green.styl. (This allows you later to combine some variables files)

add the theme link in the main gruntfile, ‘stylus’ section:

1234567891011121314

stylus:{green:{options:{import:['theme-green','utils']},files:[{src:[// here you can eventually add/remove some components from the output'node_modules/topcoat-*/src/**/*.styl'],dest:'css/topcoat-green.css'}]}}

Now run grunt and you’ll see your final topcoat-green.css and topcoat-green.min.css appear magically in the CSS folder :)

You also have a demo/topcoat-green.html file for free that show you the final result, generated via TopDoc.

Add a custom component

Now, let’s say you want to add a custom button to the generated theme, for example button-round.

Once again, i’ve been lucky enough to go to Amsterdam today to attend the Phonegap Europe annual conference.

The venue was great, the talks covered various subjects, and, most importantly, the atmosphere reflected a positive and healthy community : open-minded and confident in the open web as a major platform for the future of mobile applications.

Almost 2 years after Adobe took control of Nitobi (the team behind the Phonegap genesis), the Phonegap project is in a great shape, dynamic, more open than ever, and with a sane and solid codebase, powered by node.js and a modern javascript toolchain, thanks to the hard work of the core team and many contributors.

With the 3.0 version, released a few weeks ago, Phonegap is now mature and flexible enough to serve as a foundation for your various mobile projects. Every single plugin has been extracted from codebase, which is now focused on bridging performance and plugin management.

Phonegap is the perfect example of how open source can increase code quality and grow a solid community while serving a company business.

Here is a quick recap of the most notable talks.

Distimo

Distimo is an app-analytic company that analyses app downloads, conversions and profits and compute smart data for the app developers.

They shared some interesting metrics :

33% of worlwide app revenues comes from Asia.

Globally, ~65% of revenues comes from the AppStore and ~35% from Play Store (growing fast).

Untappd

Demo of one of the most successfull Phonegap apps : Untappd, a beautiful beer-centered social network app with 700k users and 4 stars rating. Join now !

Blackberry loves the web

Too late maybe ?

Native UI in Phonegap Apps

Tanaka Masahiro demoed the Monaca hybrid framework which gives you the ability to add native UI elements to your Phonegap app. You can wrap the phonegap webview with native tabbar/navigation bar to improve your UX, specially revelant on older Android devices. The framework also allows native transitions between various webviews, but this breaks application state. The framework hasn’t yet migrated to phonegap 3.0 so not usable as is IMHO.

Interesting real hybrid approach that demonstrates again that Phonegap is not necessarly a “full web” solution, but you can use as much “native” stuff as needed.

WizCorp HTML5 gaming

Yes you can build great games with Phonegap. You don’t necessarly draw directly inside the webview, but as phonegap is very open and extensible, you can easily plug native features as needed, like Ejecta (off browser canvas+audio for iOS), webGL views… WizCorp team shares some interesting code on their github, like a native spinner, navigation views helper…

Chrome Cordova plugins

This may be the biggest announce of this event : We can now use Chrome APIs right in our cordova applications. For the moment, we just have socket, storage, notifications, and identity (oauth), but in a near future, we’ll see support for syncFileSystem (synced data across devices) and more.

Basically, this means that you can code a Chrome Packaged App using only chrome APIs, then distribute it on desktop via the chrome store and then on mobile app stores using cordova !

This is very early stage but Google puts some efforts to stabilize and extend capabilities quickly.

Testing with appium.io

Fil Maj demonstrated appium, an open source end-to-end testing platform that fully support phonegap applications. You can write automation scripts (think selenium) then run them on your own devices, or use appium infrastructure to run the tests on various devices and produces detailed reported.

In a world of such devices fragmentation, this can be very useful :)

Firefox OS

Phonegap now also support Firefox OS ;) and Firefox provides many more javascript APIs, like ‘Activites’ (think Web intents). If you support the real open web, Mozilla is definitely the way to go :)

Phonegap CLI

This awesome talk by Michael Brooks was the most interesting and technical talk of the day. Michael showed us how powerful the cordova and phonegap CLI are. Based on a cutting edge javascript architecture, the phonegap CLI is made of nodes modules that you can use directly in the CLI, or as external nodeJS modules, which allows you to integrate the whole workflow in third-party tools and vice-versa. open source power :)

He also demonstrated how easy it is to create and compile apps with or without the locally installed SDKs, using phonegap build as a fallback. Just run for example phonegap compile ios from your machine, then in seconds you get back a QRcode that you can scan to test your final app on a real device instantly; neat !

Finally, a big thanks to Colene, Peter Paul Koch and all the Phonegap team for this event, can’t wait for next year :)

After my morning twitter rant about npm install > pip install i need to add some clarifications and explain why i meant. Basically i meant that npm is much easier to use from a user perspective, which is an essential point to grow a community. Package management and dependencies is an important part of modern application development workflow and thus needs high consideration.

npm (node packaged modules) was released at end of 2011 and for sure it’s inspired from many other packages manager while removing their commons hassles. Also, its used both on backend and on frontend projects (eg: AngularJS+grunt).

you need to configure it and run cryptic commands to activate virtualenvs

you can install virtualenvwrapper to make thing easier though

you still need to configure it though

a fresh pip install in a project containing the standard requirements.txt does nothing

On the other side, npm is a no-brainer to use :

npm install installs/upgrades any project dependencies

there’s no notion of virtualenv, it just uses what you have in the current node_modules folder or in your global install.

Both are for sure very powerful tools that goes far beyond this basic usage but this is daily work for the developer and also the first contact when entering a new project so it should work seamlessly.

Group elements in a select

For example you can easily group a model by attribute to have a nested select menu :

1

<selectng-options="distrib.version group by distrib.name for distrib in distribs"></select>

Of course, just add an ng-model directive to your select to data-bind it to one of the values.

Filter falsy values

You can’t use the builtin filter for falsy attributes or values :/ I don’t know if this is a bug of feature, but a simple workaround is to use a custom filter function that you can expose on the scope. (you can also define your own filter).

Filter on objects

The builtin filter function is quite powerful and allows you to filter a list of objects on given properties only, or on everything, exactly or not, negated or not, etc…

12345

{{ games|filter:'street' }} // all games containing "street" in any property
{{ games|filter:'!street' }} // all games NOT containing "street" in any property
{{ games|filter:{name:'street'} }} // all games containing "street" in their name
{{ games|filter:{name:'street'}:true }} // all games named exactly "street"
{{ games|filter:{name:'street', device:'PS3'} }} // all games containing "street" in their name and PS3 in their device

ng-repeat with duplicate items

If for some reason you need to have duplicate items in your ng-repeat you can extend your ng-repeat expression with track by $index and it works :)

Directive : parse attribute without watching it

In one of your directive, if you need to have a read-only access to an attribute model, but without the automatic watch/binding, you can simply use & instead of = when declaring the binding in the scope. You’ll then be able to access the model value . (this may break in future releases). This is a shortcut for using the $parse service on the current scope.

Express testing

You know you should write serious tests suites ? There’s everything to help you in AngularJS with Karma test runner + Jasmine.

Once you have many tests, they can take some time to execute and there’s a little trick to speed you up : you can limit the test-runner to a given test group by using ddescribe instead of describe and to a single test with iit instead of it.

That’s awesome to focus on specific tests for a while.

Service decorators

You can easily decorate and modify any existing service or directive. That’s how the ngMobile overrides the ngClick directive to handle transparently the FastClick behaviour.

Here’s an exemple that overrides the $sniffer service and fix the animation detection for older androids devices (landed in ef5bc6c) :

I’ve seen some developers quite shy about AngularJS when confronted to all the magical powers; don’t be afraid, AngularJS indeed introduces several new concepts but you can get them in just a few weeks of practice… The Google team is working hard to lower the Angular entry barrier and to make everything as simple as possible for developers.

AngularJS is a new disruptive innovation in the Javascript frameworks world and it prefigures the future of web browsers : templates, data-binding, web components…

In this post i’ll give some advices for the AngularJS newbies and share with you the best pointers to learn and understand the core concepts quickly.

First, to understand AngularJS you of course need to know a bit of Javascript. If you’re not comfortable enough yet, pick a free book on JSbooks and practice.