Au revoir Django forms

A few months ago, I released version 0.1.0 of django-rest-fomly, and I think that it’s time to speak about the project. First, I’ll speak about the reasons motivating me to start the project, then I’ll speak about the tool itself.

1. Why django-rest-formly ?

I start using Django since 2011, and I really like it, especially because it’s a real web framework and there is a great and active community behind it. From a design perspective, I like the fact that it emphasizes DRY and CoC principles. Besides, Django comes with powerful batteries making web development rapid, including forms, templates, admin site, ORM , etc. I like all these packages, but I think that some of them, like forms, aren’t useful anymore.  Nowadays, we speak about Single Page Application (SPA), web 2.0 and Internet of Thing (IoT). In such world, there is no need for Django forms package. Yep, there are a lot of packages developed for web 1.0 and the DSF community is aware of it. In fact, they’re acting according to this reality. On December 2015, Mozilla awarded $150,000 for rewriting Django to support WebSocket and to integrate key parts of Django REST Framework, among other things (more information here).

As a software engineer, I understand the importance of separating backend from frontend, and this is what I do. This is a good practice that you had to adopt if you aren’t. One of the advantages of this practice is the possibility to use the best tool for each part. Personally, I use AngularJS in the frontend, the Angular application communicates with the backend through a RESTful interface built using Django REST framework. However, I found myself writing by hand what Django forms was doing for me, and I didn’t like that, this is a waste of time. I spent a lot of time looking for a solution that I can use to solve this problem but I didn’t find any frontend package. So, I decided to create a generic solution to this use-case.

The idea was very simple. I need an Angular module which could replace Django forms package. In other words, this angular module should be able to create forms from a configuration object, add validation for fields, etc. Generally, I didn’t like the idea of building something from scratch, especially if I find something very powerful. In my case, it was the angular-formly module: It offers all that I expect and more, but the configuration structure is not compatible with the Django REST framework. angular-formly expects something like this:

{
    key: 'email',
    type: 'input',
    templateOptions: {
        type: 'email',
        label: 'Email address',
        placeholder: 'Enter email'
    }
}

below Django REST metadata for email field:

{
  "actions": {
    "POST": {
        "email": {
            "type": "email",
            "required": false,
            "read_only": false,
            "label": "Email address"
        }
    }
  }
}

Now, I think that the idea becomes clear. django-rest-formly project gives you MAINLY a CLI tool able to create an angular-formly form configuration object for any Django REST endpoint.

2. Installation

django-rest-formly is a CLI tool build on top of Node.js. So,  you can install it with npm (Node Package Manager) :

$ npm install -g django-rest-formly

3. How to use it

If you already installed the package, the django-rest-formly command should be available. django-rest-formly has two commands:

  • list: which list all available endpoints from the root API
  • form: which return the angular-formly form configuration for a given endpoint

Let’s suppose that we have a REST API at http://127.0.0.1:8000/api/v1/, I can list all existing endpoints with this command:

$ django-rest-formly list --host 127.0.0.1 --port 8000 --root /api/v1
Available endpoints:
  snippets: http://127.0.0.1:8000/snippets.json
  users: http://127.0.0.1:8000/users.json

To have an idea about the users’ endpoint, we had to use the form command:

$ django-rest-formly form --host 127.0.0.1 --port 8000 --root /api/v1 users

I think that it’ll be better that you interact with the tool. So I recommend you to follow the below steps:

1) clone the django-rest-framework-tutorial repository from my GitHub account: if you have git installed, just run

$ git clone http://github.com/benzid-wael/todo

2) Now, install create a python virtual environment and install the dependencies:

$ cd /path/to/django-rest-framework-tutorial
$ virtualenv --no-site-packages env
(env) $ pip install -r requirements.txt

3) Now, we can start the server

$ python manage.py runserver

Super! To list all available endpoints, just run the below command:

$ django-rest-formly list --host 127.0.0.1 --port 8000
Available endpoints:
  tasks: http://127.0.0.1:8000/tasks.json
  users: http://127.0.0.1:8000/users.json

Now let’s have a look into the tasks endpoint, we’ll use for that the form command:

$ django-rest-formly form --host 127.0.0.1 --port 8000 tasks

Now you can use the JSON output, to generate the correspondent form to your endpoint with form validation in place:

/* global angular */
(function() {
  'use strict';

  var app = angular.module('djangoRestFormlyExample', ['formly', 'formlyBootstrap']);

  app.controller('MainCtrl', function MainCtrl(formlyVersion) {
    var vm = this;
    // function assignment
    vm.onSubmit = onSubmit;

    // variable assignment
    vm.author = { // optionally fill in your info below 🙂
      name: 'Wael BEN ZID<span 				data-mce-type="bookmark" 				id="mce_SELREST_start" 				data-mce-style="overflow:hidden;line-height:0" 				style="overflow:hidden;line-height:0" 			></span>'
    };
    vm.exampleTitle = 'Introduction';
    vm.env = {
      angularVersion: angular.version.full,
      formlyVersion: formlyVersion
    };

    vm.model = {
      note: "",
      score: 0
    };
    vm.options = {
      formState: {
        awesomeIsForced: false
      }
    };

    vm.fields = DjangoRestFormly.toFormly(formFieldConfig);

    // function definition
    function onSubmit() {
      alert("You clicked on 'Submit' button");
    }
  });

})();

Hope you enjoyed the tutorial.

Advertisements

Testing angular 2 apps: Part 1 – Introduction

In this series, I’m going to show you some tips about writing unit tests in Angular 2 with Jasmine framework. Right now, it’s hard to find up-to-date recipes to write unit tests for Angular 2 (version 2.4 exactly). But, I hope that this series will provide you with some materials to get you going.

1. Angular testing module

Angular 2 requires you to import your testing methods from @angular/testing, including Jasmine functions aka describe, beforeEach, it and so on.

import {
  describe,
  expect,
  beforeEach,
  it,
  inject
} from '@angular/core/testing';

But this is not something that you had to memorize. In fact, if you use angular-cli to seed your project which I recommend. You’ll get always the minimal code for unit testing for the unit under test (component or service, etc.). If you run the following command

$ ng generate service user-profile

angular-cli will generate two files for you:user-profile.service.ts and user-profile.service.spec.ts. The .spec file will look like:

import { TestBed, async, inject } from '@angular/core/testing';
import { UserProfileService } from './user-profile.service';

describe('UserProfileService', () => {
   beforeEach(() =>; {
     TestBed.configureTestingModule({
       providers: [UserProfileService]
     });
   });

   it('should ...', inject([UserProfileService], (service: UserProfileService) => {
     expect(service).toBeTruthy();
   }));
});

So what we have here ? We imported some testing utilities from Angular 2, three exactly:

  1. TestBed: which is very similar to NgModule, as it helps to setup dependencies for the defined tests. This dependencies should be passed to .configureTestingModule() and it’ll be used to resolve any dependency.
  2. async: In fact, we need to use async when dependencies involve asynchronous processing (XHR calls)
  3. inject: allow us to inject dependencies at the TestBed level

2. Dependency Injection

As mentioned earlier, We use TestBed to declare dependencies for out test suites. We had to use inject to get dependencies at TestBed level.

   it('should ...', inject([Service], (service: Service) => {
     expect(service).toBeTruthy();
   }));

If you need to get the dependency at component level, you need to use the
component injector which is a property of fixture’s DebugElement.

describe('MyComponent', () => {
   beforeEach(() => {
     TestBed.configureTestingModule({
       declarations: [ MyComponent ],
       providers: [ MyService ]
     });
   });
it('should ...', () => {
    let fixture = TestBed.createComponent(MyComponent);
    let service = fixture.debugElement.injector.get(MyService);
  });

});

WARNING: DON’T CREATE THE SERVICE USING THE CONSTRUCTOR. Don’t think even about it. This is neither safe nor maintainable.

Now, we can refactor the code using Jasmine’s beforeEach function so we don’t repeat this snippet for each spec.

describe('MyComponent', () => {

   let component: MyComponent,
       service: MyService,
       fixture: ComponentFixture<MyComponent>;</pre>

   beforeEach(() => {
     TestBed.configureTestingModule({
       declarations: [ MyComponent ],
       providers: [ MyService ]
     });
   });

   beforeEach(() => {
     fixture = TestBed.createComponent(MyComponent);
     component = fixture.componentInstance;
     service = fixture.debugElement.injector.get(MyService);
   });

   it('should ...', () => {
     expect(service).toBeTruthy();
   });
});

3. Testing coverage

Generally we need to test everything in our application including Pipes, Services, Components and custom classes. Our tests should cover logic written with TypeScript, generated DOM, emitted events, etc.

Hopefully, angular-cli provides a rich test command. In fact, it provide the –cov parameter,  which will generate a test coverage report for your project. Furthemore, if you use a CI server, you can display a nice report using Cobertura plugin for example. You can find below an example:

cobertura-example.png

Thanks for reading! Have any questions? Ping me at @benzid_wael. In the next posts, I’ll show you how to write tests for services, components, etc.

TypeScript

Personally, I think that the most awesome Microsoft innovation in the web is the TypeScript language. TypeScript is an interesting  evolution of JavaScript. Indeed, TypeScript is for JavaScript much like what C++ was for C back then. It defines a superset and powerful facilities for the JavaScript language, which make developer life easier.

Installing TypeScript on Linux

Nothing special here, TypeScript is delivered as a Node.js module

sudo npm install -g typescript

Why TypeScript ?

TypeScript is a strongly-types superset of JavaScript. In other words, it improve the syntax of your JavaScript code.  TypeScript encourages declarative programming which we miss with JavaScript which we’ll discuss further in the rest of this tutorial.

In the other hand, Angular 2 was fully written in TypeScript and it’s developed by Microsoft. Thus, it becomes the core front-end language for the major tech companies in the world. This let me think that it’ll be probably the standard for front-end development in the incoming years.

1. Type annotation

TypeScript support most basic types you would expected in any language: boolean, number, array, etc.

var isRuning: boolean = false;
var height: number = 6;
var status: string = "stopped";
var myList: number[] = [1, 2, 3];

A helpful addition to the standard set of datatypes from JavaScript is the ‘enum‘ type.

enum Color {White, Red, Green, Blue, Purple, Black};
var c: Color = Color.White;

TypeScript also added a new type Any, as its name indicate it describe a variable which you have no idea about its type at the time of writing code. For this type we have not any type-checking.

var nonTyped: any = True;
nonTyped = "Maybe a string instead";

2. Interfaces

In real world, we need to represent more complex types (aka records). For this purpose, TypeScript define the interface keyword. Below an example from the official intro tutorial (which you can find here):

interface Person {
 firstname: string;
 lastname: string;
}

function greeter(person : Person):string {
 return "Hello, " + person.firstname + " " + person.lastname;
}

let user = {firstname: "Jane", lastname: "User"}

document.body.innerHTML = greeter(user);

In the above code, we defined an interface Person and a function greeter which
accept an object person which should implements the Person interface and returns
a string. In other words, the person object should have firstname and lastname properties.

3. TypeScript and OOP

TypeScript comes with awesome batteries that makes OOP easier for developers and manage browser-compatability for you. Below, a simple example:

class Person {
    name: string;
    constructor(name: string) {
        this.name = name;
    }
    whois() {
        return this.name;
    }
}

var person = new Person("John Doe");
console.log(person.whois())

As you see, the syntax is easy to understand; especially if you know Java or C#.

3.1. Inheritance

In addition to being able to define custom classes, you can also extend it by using extends reserved keyword. Below an example:

class Person {
  firstName: string;
  lastName: string;

  fullName(): string {
     return this.firstName + ' ' + this.lastName;
  }
}

class Student extends Person {
  major: string;
}

class Teacher extends Person {
  salary: double;
}

In this example; the Student and Teacher class inherits from the Person class.
As a result, it has access to firstName and lastName properties and to th fullName
method.

3.2. super

super is a reserved typescript keyword, which give you the possibility to call the parent method from child instance. Below an example

class Base {
    log() {
      console.log('hello world');
    }
}

class Child extends Base {
    log() {
      super.log();
    }
}

4. Typings

Geerally, we use 3rd-party libraries in our projects, like jQuery / angular.js and TypeScript expect a declaration file— denoted by a .d.ts extension —  where it can find the API definition of your library. In this stage you should know about the gigantic DefinitelyTyped repo, where you’ll find declaration of almost all JavaScript libraries. We won’t go into too much detail here, but if we wanted to use underscore types, for example, we could simply go typings install underscore --save and have them downloaded into a path defined in typings.json. After that, you could use underscore’s type definitions anywhere in your project simply by including this line:

/// <reference path="underscore/underscore.d.ts" />

5. Conclusion

TypeScript is an interesting push toward improving on JavaScript’s shortcomings by introducing a static typing system, complete with interfaces and type unions. This helps us write safer, more legible and declarative code.

Do you fill that you’ll use TypeScript in your next project ? Do you think that it’ll be the future of JavaScript ? Or do you think that it’ll fail ? Let me know what you think below!

Firefox caching and jQuery plugins

If you’re using jQuery dropdown or bootstrap_dropdowns_enhancement plugin, don’t forget to set  autocomplete=”off” in any checkbox or radio input inside the dropdown menu. Otherwise, we’ll find that the browser display a value, but send another one after submitting your form.

What’s happening ?

With normal input, the last value will be remembered by Firefox when you refresh the page, not if you hit Ctrl + F5 which will clear the value. So, your dropdown will display the default value, and Firefox will set the last checked radio / checkbox values.

The reason AngularJS will success: Part 2

As promised, this is the second round of this series :). I will discuss today, the four George’s tests listed bellow:

  • Load elements onto a page
  • User clicks on stuff
  • Use AJAX calls to…
  • Manipulate DOM elements

I will discuss his examples one by one following the order in his post:

Ajax calls

The author include the below 2 examples:

jQuery

$.ajax({
  url: '/ajax.php',
  dataType: 'JSON',
  success: function (data) {
    $('#element').html(data);
  },
  fail: function (data) {
    alert("AJAX failed!");
  }
});

AngularJS

$scope.myData = {};
$scope.myData.doClick = function (item, event) {
  var responsePromise = $http.get("/ajax.php");
  responsePromise.success(function(data, status, headers, config) {
    $scope.myData.fromServer = data.title;
  });
  responsePromise.error(function(data, status, headers, config) {
    alert("AJAX failed!");
  });
}

The author consider that jQuery have less code. But, he didn’t mention that the Angular code do more than a simple ajax call. In fact, it has this features:

  • Ajax call
  • Click event trigger
  • Two-way data binding
  • Looser-coupling with the DOM, because we don’t manipulate the DOM directly

Try to implement all this features with jQuery and you will see how AngularJS care for your time and the quality of your code. Furthermore, $http service supports JSONP and managing HTTP headers explicitly and in a fashion way.

DOM Manipulation

For this section, the author used the below example:

var myApp = angular.module('myApp', []);

myApp.directive('myWidget', function() {
  var linkFn;
  linkFn = function(scope, element, attrs) {
    var animateDown, animateRight, pageOne, pageTwo;
    pageOne = angular.element(element.children()[0]);
    pageTwo = angular.element(element.children()[1]);

    animateDown = function() {
      $(this).animate({
        top: '+=50'
      });
    };

    animateRight = function() {
      $(this).animate({
        left: '+=50'
      });
    };

    $(pageOne).on('click', animateDown);
    $(pageTwo).on('click', animateRight);
  };
  return {
    restrict: 'E',
    link: linkFn
  };
});

Firstable, I should notice here that he does not attack this part properly, because Angular directives are a sophisticated solution in which the purpose is extending the HTML by designing reusable component. Personally, I would appreciate that he starts by introducing Angular templating and built-in directives such as ngClick, ngHide, etc.

Secondly, the author hated the fact that we use jQuery in the above example . It’s clear now that he didn’t make any effort to understand why MVC frameworks, like AngularJS, have seen the light: Angular developers don’t want to replace jQuery but they want to provide a set of utilities to facilitate the creation of maintainable front-end applications. Indeed, they use jQuery or jqLite to manipulate the DOM.

jqLite is a tiny, API-compatible subset of jQuery that allows Angular to manipulate the DOM in a cross-browser compatible way. jqLite implements only the most commonly needed functionality with the goal of having a very small footprint.

Scalability

This is the most interesting section, in which we can see the quality of applications that the author write. I don’t want to discuss this because maybe he have some reasons that I can’t imagine. But personally, I do anything to avoid write such a code. Yet, We can use this use case to highlight the power of AngularJS.

The author should separate the logic from the view. So, the back-end should send real data:

{
  products: [
    productA : {
      productId: 345,
      name: "product A",
      price: 120;
      imageURL: "/public/uploads/products/productA.png",
      description: "this is the description of product A",
      colors: ['red', 'blue'],
      sizes: [34, 36, 40]
    }
  ]
}

We will define a Product service to wrap product list endpoint. For this use case, Angular provide an ngRessource module that make it easy to consume REST APIs.

var productServices = angular.module('productServices', ['ngResource']);

productServices.factory('Product', ['$resource',
  function($resource){
    return $resource('products/:productId.json', {}, {
      query: {method:'GET', params:{productId:'products'}, isArray:true}
    });
  }]);

The controller should look like this:

myApp.controller('ProductList', ['$scope', 'Product', function($scope, Product) {
  $scope.products = Product.query();
}]);

and at the view level, we will have something like that:

<ul>
  <li ng-repeat="p in products">
    <img src="{{ p.imageURL }}"/>
    <span>{{ p.name }}</span>
    <b>Price: </b>{{ p.price }}
    <p>{{ p.description }}</p>
  </li>
</ul>

As you can see, the Angular solution is easier to understand, more elegant, more structured and less code (10/48 lines only !).

Finally, I notice that if you don’t want to send the whole data for any reason, you should send a patch for the modified data. Then you merge it with the existing one at the client level (on your Angular $service). Here comes the magic of AngularJS which supports two-way data binding.

The reason AngularJS will success: Part 1

Recently, I read ‘s post “the reason AngularJS will fail“, that reduce AngularJS’s value. In my opinion, he compared it with jQuery which are incomparable. Also, the result of the comparison is false.

Let’s discuss the idea of comparison: jQuery is a cross-browser JavaScript library designed mainly to simplify document traversal and manipulation. However, AngularJS is a client-side framework (a framework is a collection of software libraries providing reasonable default interface, and generally driven by patterns). In other words, the main differences are:

  • Libraries are generally more expressing
  • Libraries allow us to learn the API as needed
  • Framework requires holistic understanding
  • Framework bring structure to large amount of code

As you see comparing jQuery to AngularJS is like comparing a text editor to an IDE, this does not means that the text editor is not more useful, but simply because the IDE has a big scope of features than the text editor. Eventually, you can extends the text editor with new features such as auto-complete, syntax highlighting, etc and you will have an IDE.

Is AngularJS difficult ?

According to the author, Angular will fails because it’s difficult. First of all, I agree with him that AngularJS is more difficult than jQuery, and that’s intuitive because frameworks are always more difficult than libraries, but this difficulty bring us more modularity, maintainability and testability, and make both development and developer’s life more easy. However, I don’t agree with him that Angular is difficult. It’s clear that it’s not intuitive but it doesn’t mean that it’s difficult, you can learn AngularJS fundamentals in 60 minutes (see this video), yes absolutely in just 60 minutes.

In the other hands, frameworks doesn’t fail because they are difficult, but they fail if their difficulties are not worth the results they produce. A chain saw is more difficult than a saw: you must be sure that it’s fuelled up and oiled. But is it useful? If you don’t want to burden your head with application architecture and best practice, just use jQuery and manipulate the DOM by your hand and you will discover as soon as your application grow that your code sucks and you not find any solution than rebuild it from scratch using any JavaScript framework.

Is AngularJS sucks ?

Another point discussed in the first author’s part, is that « doing a google search on “jQuery sucks” vs “AngularJS sucks” shows that there are more results for the latter ». Wow !! this is very convincing. Let’s try to compare each one features in an objective way:

jQuery VS AngularJS
jQuery VS AngularJS

I notice, that we can extend jQuery’s features using 3-rd party libraries and jQuery plugins.

Finally, I want to reminder you that jQuery is a wonderful library, but it can not replace any JavaScript framework. So, when you’re in a situation that jQuery is all you need then you SHOULD USE IT.

I’m gonna discuss the rest of his post in my next posts.

JavaScript Tips

JavaScript is one of the most used languages on client-side, most of the websites you know contains some JavaScript code even if it’s not so important. Nowadays, this use exploded, especially with the introduction of MV* frameworks on client-side such as BackboneJS or AngularJS, etc. In this post I’ll speak about some JavaScript tips that I learned in my carreer. I’m not a JavaScript specialist, so your comments are welcome.

1. Global variables

Don’t forget to use the var keyword when declaring variables, because if you don’t do, this will be interpreted as a global variable and this is not a good habit because it will make the debugging more difficult.

2. Testing equality

Try always to use === instead of == when testing equality, because === operator evaluates both type and the value

if(1 === '1') //Returns false
if(1 == '1') //Returns true

if(0 === '') //Returns false
if(0 == '') //Returns true

Note that this is the same advice for inequality operators != and !==

3. Semicolons

Always include all semicolons, why ? Because when you didn’t do it, the browser will do it for you where he thinks that is the best and necessary place. So imagine what could be the results.

4. Blocks

Like in C programming language, It’s preferred to use the K&R style of formatting for block quotes. This format starts the opening curly brace on the same line as the preceding line of code. Below, an example:

if(debug === true) {
   console.log('DEBUG mode is enabled');
} else {
   console.log('DEBUG mode is disabled');
}

Furthmore, you should always use explicit blocks. So it’s not appreciable to write the below code

if (i < 10)
    do_something(i);

Instead, write:

if (i < 10) {
    do_something(i);
}

5. Variables declaration

One of the most strange notions in JavaScript that encounters developers coming from C-family languages is the fact that variables is hoisted: variables are available before declaration. It’s strange ! This is due to the interpreter’s strategy. The interpreter starts with scanning code and retrieving all declarations, it executes code line by line. This is why the below code does not throws any error:

console.log(my_variable);
//Outputs: undefined

var my_variable = "Hello World!";
console.log(my_variable);
//Outputs: Hello World!

So, the interpreter scans the code, and collect all declared variables and put them in the concerned scope, then it executes the code. In our case my_variable is declared but it’s not yet initialized until the 4th line. This why the output was undefined for the first time.