Four days in Paris for ng-europe

Last Sunday, October 19th, I flew to Paris to spend four days in the first AngularJS conference in Europe. And these is my summary and some notes about the great experience there.

Full Day Workshop with egghead.io

Monday was the start with a full day training by John Lindquist and Joel Hooks. And I have to say that was pretty impressive to have them in front of us after watching so many of their videos at egghead.io.

But the workshop itself was rather disappointing and it would have been better called “Introduction to AngularJS” with basic usage of controllers, services, ui-router and directives.

For those more experienced with the framework they offered us two challenges building a grid and a shopping cart with the data provided in their egghead-board-game-store repository.

But there came the biggest problem of the conference and it’s that the WiFI of Espace Charenton was terrible and didn’t support the load. So they had to pass the files in a USB key throughout the room but even after, I wasn’t able to run a clean npm install of the dependencies in the whole day.

It was an unproductive day but the slow internet connection and the use of verbose output inspired my colleague Samuel to build with fun the plugin BeBusy.js.

AngularJS Sprint with Vojta Jína

After a disappointing start of the week, on Tuesday we headed to the nice office of Valtech and the place was quite comfortable with internet running smoothly.

Rodric Haddad leaded the event from the start to the end while Vojta Jína and Jeff Cross joined straight from the airport around noon. The sprint consisted in choosing one or more of the tagged issues pending of pull request and try to fix them.

It was great to dig into the roots of the framework and I managed to fix a small issue with the $observe method. Having first hand help from the experts was amazing and after the pull request was merged I can say that I’m one of the +1000 contributors to the core.

As a prove I got a great AngularJS t-shirt and also won an Anker external battery and a monopod (selfie stick) from the sponsors.

Conference Day 1

Wednesday was the big day and the conference opened with Judy Tuna singing about AngularJS; followed by a funny talk between Igor Minar and Bradley Green.

There was really great talks during the whole day but I was highly impressed by the speed while coding of Andrew Joslin in his presentation of Ionic framework to build hybrid mobile apps with AngularJS.

Vojta carved the sentence of the day “Most code is broken and we don’t know why.” during his session “Can We Learn from Architects?”.

I liked to discover Dgeni which is a tool to generate documentation and was nicely explained by his author, Pete Bacon Darwin.

I learned a bit more about Protractor during the talk of Julie Ralph and Chirayu Krishnappa who gave some interesting insights like the Page Objects to re-use elements and browser.pause() for debugging.

And Matthieu Lux was able to build AngularJS from scratch showing the magic behind the framework with special thanks to Tero Parviainen, author of the book “Build your own AngularJS”.

Lightning talks contest

After a full day with thirteen talks by the professionals, there was time before dinner for regular people to show their awesome projects in short talks. These are the four that I noted over more than ten featured topics:

The winner of the contest was Gabriel Obregon with his mocked backend workflow.

Conference Day 2

Thursday was opened by Miško Hevery, father of AngularJS, showcasing AtScript, built on top of TypeScript.

Miško was followed by the big talk between Igor Minar and Tobias Bosch which was probably the scariest talk because comparing 1.3 and 2.0, the latest literally kills everything from the previous: controller, directive definition object, $scope, angular.module and jQLite will be gone. Some of the syntax will be different as well but all the new changes look promising as there has been a whole re-think of the framework.

I didn’t know about famo.us but Zack Brown showed how to do complex animations with JavaScript achieving the same behaviour in the browser than that of the native applications.

Martin Gontovnikas came all the way from Buenos Aires to talk about his service Restangular to handle Rest API Restful Resources.

And the speaker who won the entire audience was Lukas Ruebbelke sitting in a chair talking about Firebase and AngularFire to build realtime apps.

Unfortunately our plane was leaving early so we missed the last four talks and the Q&A session which I’m sure were as great as the previous talks.

Conclusion

It was amazing to be part of an event like this were 850 developers met together in Paris during two days. So I have to congratulate Patrick AljordDouglas DuteilOlivier LouvignesJosh Moont and the rest of the ng-europe team as well as the sponsors for making it possible. I have to say also that the food and the wine by the chef Jean-Jacques Massé were outstanding.

The slap on the wrist in this case would be for Espace Charenton not being completely ready for such an event with their WiFi problems; which in any case should have been checked before.

I very much enjoyed meeting some of the guys working in Google and be coding side by side with them. And it was cool to meet and talk with so many great developers from everywhere in the world; but I can’t list all of them here, so cheers for all off you and see you next year!

If you want to know more about the conference there is an useful repository with collaborative notes and links to most of the slides; and the videos will be available on-line soon.

Keep calm and use AngularJS

Tagged , , , , ,

Mocking Services for AngularJS tests

One of the things that I’ve enjoyed more in the last year is Test Driven Development, with the satisfaction of seeing the green after all tests have passed. AngularJS is written with testability in mind which makes testing applications easy. And although it can be hard to grasp at the beginning, there a lot of good resources around to learn how to unit test the application logic.

But in this post I want to focus in writing mock objects. In previous versions of the AngularJS generators for Yeoman there was a mock folder generated inside of the test directory. This made me think on a way to write separated files for every necessary mock so we can include them where required. With the new structure recommendations this mock folder has been removed, but the point of writing separate files it’s the same.

Let’s say we have a complex Auth service to deal with user authentication.

angular.module('webApp')
  .factory('Auth', function($http) {
    var currentUser = {};    
    return {
      login: function(credentials) {
        $http.post('/api/auth', credentials).then(function(response) {
          currentUser = response.data.user;
        });
      }, 
      logout: function() {
        currentUser = {};
      },
      isLoggedIn: function() {
        return !!currentUser.id;
      } 
    };
  });

This service could be injected in a controller to submit a form just if the user is logged in.

angular.module('webApp')
  .controller('ContactCtrl', function(Auth) {
    this.showAlert = false;
    this.submitted = false;
    this.submitForm = function() {
      // If the user is not logged-in, return and display the alert.
      if (!Auth.isLoggedIn()) {
        this.showAlert = true;
        return;
      }
      // Handle form submit.
      this.submitted = true;     
    };   
  });
<div ng-controller="ContactCtrl as contact">
    <form name="contactForm" ng-submit="contact.submitForm()">
        <button type="submit">Submit</button>
        <div class="alert" ng-if="contact.showAlert">
            Please <a href="/login">login</a>
        </div>
    </form>
</div>

Note that for the sake of example, the code of the service has been reduced to a minimum while the form controller it’s pretty dumb; this way we can just get the idea of the functionality and focus in writing the mock object.

How to mock our Service?

Another long topic in AngularJS is the difference among Factory, Service, Value, Constant and Provider. But for creating the mock we just need to know that these five types are built on top of Provider, so the injector is going to look for an AuthProvider.

To write our Provider we don’t need to use $http to interact with the backend, as we just need to emulate the functionality.

angular.module('authMock', [])
  .provider('Auth', function() {
    this.userLoggedIn = false;
    this.$get = function() {
      return  {
        login: function() {
          this.userLoggedIn = true;
        },
        logout: function() {
          this.userLoggedIn = false;
        },
        isLoggedIn: function() {
          return this.userLoggedIn;
        }
      };
    };
  });

So we can unit test our Controller injecting the mocked Service.

describe('Controller: ContactCtrl', function() {

  // Load the controller module.
  beforeEach(module('webApp'));
  // Load the mock service module.
  beforeEach(module('authMock'));
    
  var ContactCtrl, Auth;
  // Initialize the controller and the mocked service.
  beforeEach(inject(function($controller, _Auth_) {
    Auth = _Auth_;
    ContactCtrl = $controller('ContactCtrl', {
      Auth: Auth
    });
  }));
    
  it('should submit the form if the user is logged in', function() {
    Auth.login();
    ContactCtrl.submitForm();
    expect(ContactCtrl.submitted).toBe(true);
  });
    
  it('should not submit the form if the user is not logged in', function() {
    Auth.logout();
    ContactCtrl.submitForm();
    expect(ContactCtrl.submitted).toBe(false);
  });
  
});

I have put all this code together on a JSFiddle so you can see the specs passing.

Tagged , , ,

AngularJS Capitalize Filter

Over a month ago I was messing around with CSS when I realized the text-transform property with the capitalize keyword works just with lowercase text, as it forces the first letter of each word to be converted to uppercase keeping the rest of the characters unchanged.

In the current project I’m working on I’m getting uppercased text from the Rest API so this was the perfect scenario to create my first AngularJS filter. Moreover, as we are working with team names, we need a special letter case where team abbreviations are displayed like CD Logroñés or FC Barcelona.

It was really simple for me to create this filter and I decided to open source it as it might be helpful for somebody else who needs capitalization or just as a base for developing a custom filter.

angular.module('angular-capitalize-filter', [])
  .filter('capitalize', function() {
    return function (input, format) {
      if (!input) {
        return input;
      }
      format = format || 'all';
      if (format === 'first') {
        // Capitalize the first letter of a sentence
        return input.charAt(0).toUpperCase() + input.slice(1).toLowerCase();
      } else {
        var words = input.split(' ');
        var result = [];
        words.forEach(function(word) {
          if (word.length === 2 && format === 'team') {
            // Uppercase team abbreviations like FC, CD, SD
            result.push(word.toUpperCase());
          } else {
            result.push(word.charAt(0).toUpperCase() + word.slice(1).toLowerCase());
          }
        });
        return result.join(' ');
      }
    };
  });

For now it has just three options: capitalize all the words in a sentence, capitalizes just the first word of a sentence and the special one for team names.

You can feel free to install it using Bower or fork it from the repository.

> bower install angular-capitalize-filter
Tagged , , ,

Holiday alert module for PrestaShop

Last year I got a client that needed me to help them with the technical part of the e-commerce PrestaShop. Although I didn’t use PHP for over a year I accepted the challenge and for Christmas they wanted to show an alert to their clients because the orders wouldn’t be processed till January.

This was a good chance to dig into the process of creating a PrestaShop module and I implemented a simple module that shows a message in the top of the e-shop or in the shopping cart page.

For the layout of the box I’m using the one of Bootstrap so you can choose among four colours. This can be configured in the back-end as well as the message of the alert.

Today I have created a GitHub repository where I’m sharing the code of this module and hopefully soon there will be others.

Let me know how it goes if you use it!

Tagged , , ,

Using Grunt to run Mocha tests with Backbone.js and RequireJS

I don’t have all the time that I would like for writing here but before the end of the year it’s time for a new blog post.

This year has been really prolific for me learning new things with JavaScript and in the last months I have adopted the Yeoman workflow, which really helps to develop web applications.

One of the tools included in Yeoman is Grunt, a task runner that is used to build, preview and test the project.

In the process of converting a Backbone.js + RequireJS app to this Yeoman workflow, I had a hard time figuring the right configuration to run tests both in the command line and the browser. There are several blog posts and repositories talking about it but non of them worked for me so I’m summarizing my experience here.

I’m assuming you have created an application using Yeoman as follows:

> mkdir app
> cd app
> yo backbone

So the mocha task in the Gruntfile.js is the default one but the run parameter has to be set up to false. You can change the mocha reporter as you like and add as well options for logging so you can track any error.

        mocha: {
            all: {
                options: {
                    log: true,
                    reporter: 'Spec',
                    run: false,
                    timeout: 10000,
                    urls: ['http://localhost:<%= connect.test.options.port %>/index.html']
                }
            }
        },

I added Mocha and Chai as developer dependencies so they can be downloaded with the package manager Bower, which is another Yeoman tool. After this you can remove the lib folder inside of the test folder.

{
  "name": "backbone-app",
  "version": "1.0.0",
  "dependencies": {
    "jquery": "~1.9.0",
    "underscore": "~1.4.3",
    "backbone": "~1.0.0",
    "requirejs": "~2.1.5",
    "requirejs-text": "~2.0.5"
  },
  "devDependencies": {
      "mocha": "*",
      "chai": "*"
  }
}

Another key point was including the test framework and the assertion library inside of script tags in the HTML code and not trying to load them using RequireJS.

<!doctype html>
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    <title>Mocha Spec Runner</title>
    <link rel="stylesheet" href="bower_components/mocha/mocha.css">
</head>
<body>
    <div id="mocha"></div>

    <script src="bower_components/mocha/mocha.js"></script>
    <script>mocha.setup('bdd')</script>
    <script src="bower_components/chai/chai.js"></script>
    <script>var expect = chai.expect</script>

    <script data-main="spec/runner" src="bower_components/requirejs/require.js"></script>
</body>
</html>

Then I created a spec runner which is the main entry point for RequireJS to load the test files and its configuration.

'use strict';
require.config({
    baseUrl: 'scripts/',
    paths: {
        jquery: '../bower_components/jquery/jquery',
        backbone: '../bower_components/backbone/backbone',
        underscore: '../bower_components/underscore/underscore'
    },
    shim: {
        underscore: {
            exports: '_'
        },
        jquery: {
            exports: '$'
        },
        backbone: {
            deps: ['underscore', 'jquery'],
            exports: 'Backbone'
        }
    }
});

var specs = [
    'spec/collections.examples.js',
    'spec/models.example.js'
];

require(specs, function() {
    mocha.run();
});

Now you can create a test file for a Backbone collection like this:

/*global define, describe, it, expect */
'use strict';
define(function(require) {
    var ExamplesCollection = require('collections/examples');

    describe('Examples collection', function() {

        var examples = new ExamplesCollection();

        it('should exist', function() {
            expect(examples).to.exist;
        });

        it('should be an instance of Examples collection', function() {
            expect(examples).to.be.an.instanceof(ExamplesCollection);
        });

    });

});

To run the tests through the command line you just need to run grunt test. If you want to run them in the browser load http://localhost:9001/index.html after typing grunt server:test.

Don’t forget as well to run bower install to download the dependencies and check that the app folder is being mounted for the test task.

            test: {
                options: {
                    port: 9001,
                    middleware: function (connect) {
                        return [
                            mountFolder(connect, 'test'),
                            mountFolder(connect, yeomanConfig.app)
                        ];
                    }
                }
            },

Merry Christmas and Happy Coding!

Tagged , , , , ,
Follow

Get every new post delivered to your Inbox.

Join 1,041 other followers