Sharing common libraries and own modules between multiple angularJS projects

I have multiple projects that I’ll develop using AngularJS, but targeting to web and phonegap at a time. The problem is that I have shared/common UI components (services, controllers, filters …) between these projects for reducing maintenance effort. All the projects will have their own modules with specific functionality. But technically we have to bring the common modules into each project (without copy-pasting them, obviously).

This scenario is to assume that your project could be large, and many small teams could work together at a time. Sharing common things that could prevent the code missing from updates, but it produces less DRY code and does not violate KISS principle. As I do mention about sharing common codes that this part should be far away from recent requirement changes … If the changes alway happen among the teams, sharing common things could be a nightmare.

My inspiration comes from developing application with Sencha ExtJS. This framework is awesome in separating the application into multiple targeting such as web, phone, tablet. It’s about the structure source code, and build process that collects appropriate codes that matching target devices.  With AngularJS projects, we can share the common libraries with bower, using module to split application into several profiles (phone, web …) or you know that you can have multiple ng-app in one prject. Grunt is the best tool for developing your own build process.

From beginning, I cloned the angular-seed project, start to modify it with multiple profile. It’s easy that you just create new folder ‘profiles/phone’ and ‘profile/web’ and copy the ‘view1’, ‘views2’ modules for both. Don’t forget app.js, app.css …  At this point, you have 2 application that share bower_components,  components as well. You can start the server and see them working separate parts of a single large web application. It should be worry that we could public all the things to user, but we don’t do that because the source should be minified and deployed for separated target.

To create the build for phonegap, I have the idea that is to collect the code from bower_components, commons, components folder, and profiles/phone . All the JavaScript code, css and html resource will be minified and copied into www folder in phonegapp package. So the most important here is grunt task, no more specific technical stuff. The same idea for web targeting, and grunt task would deploy this part to appropriate location.

I posted my solution to github, with detail instruction in readme file. All they’re kept to be update, since I am getting several feedback by my technical team. This simple solution have challenged many developers for a while, because of not deeply understanding on Front-end architecture. So, just a K.I.S.S 🙂


Isomorphic Web Application – AngularJS is possible loser by ReactJS or my MEAN stack confusing story


I am Google Fan – but seems never interesting with AngularJS.

I am anti Facebook – but seems getting interested with ReactJS.

I have been working with Java as primary server side technology, JavaScript by NodeJS seems like an alien to me

This article is not introducing about reactjs, nor comparing angularjs with reactjs

isomorphic web application

If you want to understand about isomorphic web application – visit because of shorten explanation, a lot of useful articles, links …

By 3 years, nothing else attracting me than the term “isomorphic web application – iwa”. This term is new to me, along with SPA (Single Page Application) that I have been working on for a year. The fact that most Web Development Companies in Vietnam are now interesting with MEAN stack, requesting developers must be familiar with AngularJS, NodeJs … Most Technical Leader telling much about NodeJS, despite of their explaining is about building an eco JavaScript application – both server side and client side that implementing unique JavaScript, but the confuse is while JavaScript can be executed by server side, why do we keep continue using it in client side ?

AngularJS is complete MVC framework, but needs DOM elements to bootstrap, renders HTML page. I used to wonder that pull down AngularJS running in server side, but so painful that no DOM elements within server side (do not mention phantomjs – it’s about different context, story …)

Routing – for the most MVC frameworks like Spring, Playframework, or RoR … developers are easily to recognise that happens in server side code, but weird in client side. The MEAN stack is offering both routing for client side (AngularJS) and server side (ExpressJS). Imaging that your developers discussing about routing but not determine which side.

As usual, the pipeline to server a page should be: route -> fetch -> parse -> render

The MEAN stack pipeline: route (server) -> fetch (server) -> parse (server) -> render (client) -> route (client) -> render (client – actually renders DOM). The server side could be executing one time for application lifecycle, why wasting effort to do server side routing ?

Isomorphic is a big deal, not for routing but also aiming view, data, event handling (see the discussing), developers who wanting apply ReactJS/Flux should consider about isomorphic web application.

[Automation] Who should write the automated tests ?

Starting involve deeply into automation test. Thought it’s more challenge than coding. My conclusion:
Automation test is for developer, not for tester. Since only developer knows about classes, IDs, data work flows. Of course, developers have their own big picture about application.
Almost Manual testers cannot perform coding, or their code could be harder for understanding than typical developer.
Agile produces more changes than ever process, so only developer can produce both codes and test script at a time.

[pureMVC] Javascript version – bình mới rượu cũ

Cách đây vài năm, khi Flash/Flex development còn phổ biến thì pureMVC được xem như là một trong những framework mẫu mực dành cho công nghệ này.  Nếu bạn từng là một flash/flex developer, bạn chắc hẳn đã từng sử dụng hoặc nghe về framework này. Bản thân pureMVC – như tên của nó làm một framework thuần túy theo pattern MVC nên nó được port sang rất nhiều các ngôn ngữ phổ biến như Java, C#, Python … Javascript cũng không ngoại lệ.

Một số thống kê gần đây cho thấy pureMVC không nằm trong danh sách các framework javascript phổ biến như thống kê dưới đây chẳng hạn.

Theo quan điểm cá nhân của tôi thì bản thân pureMVC không thật sự hỗ trợ tốt cho HTML (tương tác với DOM object, hỗ trợ HTML template, partial …). Tuy được port sang nhiều ngôn ngữ nhưng nhóm tác giả pureMVC lại không cập nhật và phát hành thường xuyên, có lẽ vì ít người sử dụng nên hầu như không có nhiều feedback cũng như bug report.PureMVC là một framework gắn liền với Flash /ActionScript nên các lập trình viên HTML/JS cũng ít quan tâm đến framework này hơn. Bản thân tôi khi chuyển sang HTML5/JS cũng đã chọn lựa AngularJS, BackboneJS, KnockoutJS cho các project của mình hơn là pureMVC.

Điểm hấp dẫn của pureMVC chính là tính “thuần” MVC pattern của nó – bạn có thể dùng pureMVC để kết hợp với các framework Javascript chưa có MVC như CreateJS, KinectJS để từ đó tạo ra các project có cấu trúc tốt và dễ bảo trì.  Bạn có thể tham khảo source từ  hoặc từ app-seed project mà tôi đang thực hiện.

[Android] ADB is unabled to connect my China phone – HiSense U950 (aka HiSense F1)

That was crazy time !

I just bought a cheap android phone for my incoming projects. Yes, budget was my very first issue that I could not bought expensive phone such as Samsung Galaxy S3, or Note 2 (just my dream) . So I decided to buy a cheap phone – Hisense F1, which price is arround 110 usd. My Android development experience takes me to this site, then download the USB driver. But no look, the link is just … broken, and it seems about the smart TV product, not smartphone !!!

A guy from just posted some stuff rooting this phone, so I could found the link to download its driver.  So I thought just downloading driver, then everything would work well as I did with my HTC Cha Cha or Motorola Droid before.  Opening the adb and check connection

C:\Android\android-sdk\platform-tools>adb kill-server
C:\Android\android-sdk\platform-tools>adb start-server
* daemon not running. starting it now on port 5037 *
* daemon started successfully *
C:\Android\android-sdk\platform-tools>adb devices
List of devices attached

The list was just empty !!!

I know the most problems that ADB could not see the device is driver compatible, but Windows shows me that driver has been installed correctly ! Dammit …   So I came back to Android development site, read carefully about “Hardware devices” and noticed on USB Vendor ID. Just remembering that the last time I installed driver for HTC Cha Cha,  adb_usb.ini file (C:\Users\<my user name>\.android\adb_usb.ini ) has been changed for some reason, and it contains USB Vendor ID list.

# USE 'android update adb' TO GENERATE.

Yes, I did not contain the vendor ID for Hisence phones !

So I just added “0x109b” at the ending of file and restarted the ADB

C:\Android\android-sdk\platform-tools>adb kill-server
C:\Android\android-sdk\platform-tools>adb devices
* daemon not running. starting it now on port 5037 *
* daemon started successfully *
List of devices attached 
u950 device

Now, ADB can see my device …



[Sencha Ext JS 4] Unit Testing với Jasmine

Jasmine là một BDD (Behavior Driven Development) test framework có thể tích hợp vào nhiều môi trường khác nhau. Trong bài viết trước, tôi có nhắc đến Jasmine cùng với khái niệm về TDD. Thực tế thì BDD là một bản mở rộng của TDD mà thôi. Bạn có thể xem thảo luận về BDD và TTD tại đây. Về Unit testing, bạn có thể tìm hiểu qua rất nhiều các bài viết hoặc ebook nên tôi không đi vào quá chi tiết việc trình bày các khái niệm về unit testing. Quan điểm của tôi về unit testing như sau:

  • Unit testing để làm rõ và kiểm tra tính đúng đắn của specs
  • Unit testing cho thấy khả năng chia nhỏ các feature mà bạn đang hiện thực nó
  • Unit testing không thích hợp cho test UI, tốt nhất là áp dụng unit testing cho logic của ứng dụng. Bạn đặt logic của ứng dụng ở đâu (Model ? View ? ) thì hãy áp dụng unit testing ở đó.

Với ExtJS, hướng dẫn về unit testing được trình bày tương đối đơn giản và ngắn gọn, bạn nên đọc qua trước khi bắt đầu viết unit testing.  Bài viết sử dụng ứng dụng FlickrSearch  mà tôi đã trình bày từ trước, bạn có thể tìm hiều qua ứng dụng FlickrSearch. Phần trình bày về Jasmine sẽ tâp trung vào việc viết test cho 2 module Search Photo và màn hình Login. Trường hợp màn hình login là một thử nghiệm vì tôi không nghĩ mình sẽ viết unit testing cho phần UI như quan điểm trình bày ở trên.

Cài đặt Jasmine

Tôi sử dụng phiên bản Jasmine 1.3.1 – là phiên bản mới nhất tại thời điểm này. Bạn có thể thấy workspace của tôi khác một chút so với các ví dụ của ExtJS. Đơn giản là tôi thực hiện unit testing cho chính source code mà tôi đang viết.

jasmine workspace

Những module được đánh dấu là những phần thuộc về unit test. Như vậy bạn cần phải copy jasmine 1.3.1 vào project của mình. Folder specs là nơi đặt các test-case, app-test.js và run-test/html là các file để khởi động ứng dụng test.


File này khởi tạo môi trường chạy của jasmine cũng như khởi tạo các report cho các test run


var Application = null;
Ext.onReady(function() {
      Application = Ext.create('', {
      name: 'FlickrSearch',
      appFolder: 'app',
      controllers: ['ScreensController'],
      launch: function() {
         var htmlReporter = new jasmine.HtmlReporter();

Test suite cho PhotoStore

Một test-suite bao gồm nhiều test-case, trong trưởng hợp này tôi tạo test-suite cho PhotoStore và định nghĩa một số test-case trong đó.

describe("Photo", function() {
    var controller = null;
    var store = null;
    beforeEach(function() {
        if (!controller) {
           controller = Application.getController("ScreensController");
        if (!store) {
           store = controller.getStore('PhotoStore');

beforeEach (cùng với afterEach) là các hàm global – những hàm này sẽ được gọi trước (beforeEach) và sau (afterEach) mỗi test-case. Các test-case có cùng điều kiện khởi tạo và kết thúc có thể sử dụng các hàm này để khời tạo cũng như kết thúc test-case. Mục đích là để tránh lập lại các đoạn code dành cho khời tạo, kết thúc …  Trong trường hợp trên, mỗi test-case cần khởi tạo lại store và controller, nếu đặt các đoạn code này trong từng test-case sẽ dẫn đến việc các đoạn code này bị lập lại – bạn sẽ vi phạm nguyên tắc DRY – Don’t Repeat Yourself

Một số test-case cho PhotoStore

Kiểm tra việc khởi tạo controller

it("controller must be defined",function(){

Kiểm tra việc khởi tạo store

it("Store must be definded", function(){

PhotoStore không phải là 1 store autoLoad, store này được kích hoạt thông qua việc gọi hàm load nên trong trường hợp này, thuộc tính autoLoad phải là false.

it("Store should not auto load",function(){

test-case dưới đây minh họa việc test bất đồng bộ – store thực hiện một request tới server và chờ server response về . Giả định là request này sẽ phải thực hiện trong vòng 4 giây và nếu quá thời gian này, test -case sẽ fail

it("sets up latency configuration and receives latency", function() {
 runs(function() {
 store.load({params: { text: 'red' }});
 }, "an asynchronous method");
waitsFor(function() {
 return store.isLoading() == false;
 }, "store loading complete", 4000);

Sau khi thực hiện request đến server và có response trong vòng 4 giây, kiểm tra kết quả store có dữ liệu hay không

it("Store should have photos", function() {

Unit-test với UI

Theo quan điểm của tôi, UI có thể quá phức tạp để thực hiện unit-test. Với UI, nên sử dụng các phương pháp automation test sẽ có hiệu quả hơn ? Bạn có thể tham khảo thêm test-suite “authentication” mà tôi dùng để test UI. Kết quả chạy có thể thấy như sau


[Sencha ExtJS 4] Xây dựng ứng dụng Flickr Search

Trong bài viết trước tôi đã trích dẫn một phần nhỏ của ứng dụng Flickr Search mà tôi đang viết demo. Từ loạt vbài này, tôi sẽ cố gắng trình giới thiệu từng bước để có thể xây dựng một ứng dụng Flickr Search tương đối hoàn chỉnh trên nền ExtJS 4.2 . Loạt bài viết này cũng không trình bày cách thức cài đặt môi trường làm việc với ExtJS, cũng như đi quá sâu vào việc trình bày xây dựng 1 ứng dụng MVC từ con số 0. Bạn cần phải nắm về MVC pattern, Javascript để có thể theo dõi loại bài này hoặc có thể để lại comment cho bất kỳ mục nào mà bạn không hiểu hoặc chưa rõ. Nhiều bạn từng hỏi tôi về IDE /application server ?  Tôi đang sử dụng WebStorm 5.0 để coding và NodeJS để deploy ứng dụng của mình. Bạn có thể tải trước mã nguồn của ứng dụng tại đây.


Ứng dụng này sẽ gồm những gì ?

Màn hình login – hiện tại nó không có tác dụng gì ngoài minh họa cho việc quản lý nhiều màn hình khác nhau.


Màn hình PhotoSearch – màn hình này sẽ bao gồm 1 toolbar, bạn sẽ gõ từ khóa tìm kiếm ở đây


Ngoài ra, khi bạn click lên hình thumbnail, một cửa sổ popup hiện ra cho phép bạn xem hình ở kích thước lớn hơn


Bạn cần xây dựng những lớp nào ?

Trước hết, hãy xem qua screenshot project workspace của tôi


 Hãy chia ứng dụng của bạn ra các package tương ứng với M – Model , V – View , C – Controller. Dễ dàng thấy 3 màn hình mà tôi trình bày ở trên nằm lần lượt trong package view.  Trong project này tôi cũng sử dụng unit testing với Jasmine 1.3.1, tuy nhiên tôi không có ý định xây dựng ứng dụng này theo phương pháp TDD. TDD với ExtJS sẽ được trình bày trong một bài viết khác cùng với kỹ thuật Automation. Bạn có thể tham khảo file app-test.js, các file trong package specs cũng như chạy thử run-test.html.

Khởi tạo ứng dụng – app.js

     requires: ['Ext.container.Viewport'],
     name: 'FlickrSearch',
     appFolder: 'app',
     controllers: ['ScreensController'],
     launch: function() {
         var viewport = Ext.create('Ext.container.Viewport', {
         layout: 'card',
         items: [
                 xtype: 'authentication'
                 xtype: 'photosearch'
           signin: function() {
          signout: function() {

Bạn cần quan tâm đến layout: ‘card’ – layout này có thể quản lý nhiều view (hoặc component)  – các view hoặc component sẽ có kích thước fit với ViewPort và tại mỗi thời điểm chỉ có 1 view hoặc component được hiển thị. Để chuyển qua view khác, gọi setActiveItem và truyền vào index thích hợp. Ứng dụng hiện tại có 2 view – authentication (index = 0) và photosearch (index = 1)

signin signout là 2 sự kiện được gửi từ ScreensController, application bằt 2 sự kiện này để thực hiện việc chuyển đổi giữa các màn hình


Controller này hoạt động theo đúng như tên của nó – handle hầu hết các action giữa các màn hình. Nếu bạn nhìn vào các code của các View, bạn sẽ không thấy các phần logic, truy cập store …ScreensController đã làm việc này. Theo quan điểm của tôi, view thuần túy chỉ định nghĩa phần giao diện, phần logic của nó nên chuyển sang cho controller hoặc model.

Tất cả các view do ScreensController quản lý cần được khai báo trong mảng views


 views:['AuthenticationView', 'PhotoSearchView', 'PhotoView'],

ScreensController giữ tham chiếu đến các view thông qua khai báo các tham chiếu đến từng view trong mảng refs

refs: [
        { ref: 'authentication', selector: 'authentication'},
        { ref: 'photosearch', selector: 'photosearch'}

Sau khi khai báo, ExtJS sẽ tự sinh ra getter cho view tương ứng – getter dựa trên selector với ký tự đầu tiên được viết hoa cùng với từ khóa get được thêm vào ở phía trước . Ví dụ, để tham chiếu đến photosearch, ta sẽ gọi

view = this.getPhotosearch();

từ đây, bạn có thể truy cập đến các hàm, biến được định nghĩa trong photosearch

Ở trên, tôi có trình bày trong app của chúng ta đang handle 2 sự kiện là sigin và signout. 2 sự kiện này được khởi động trong controller, thực tế thì đến từ 2 handler của các action trong các view do ScreensController quản lý

 signinHandler: function() {
 signoutHandler: function() {

PhotoModel và PhotoStore

Tham khảo đến bài viết trước để có cái nhìn tổng quan hơn về 2 class này



Chú ý đến XTemplate được sử dụng trong view này. Tôi đã mất 1 tiếng để debug khi không thể render được các item từ XTemplate vì chưa khai báo itemSelector ( itemSelector: ‘div.thumb-wrap’, ). Với các phiên bản cũ của ExtJS thì itemSelector không bắt buộc (hoặc không có ?) nhưng với ExtJS 4.2 thì đây là thuộc tính bắt buộc. Tốt nhất khi sử dụng 1 component, class của ExtJS, bạn nên tham khảo document – mục config để xem các trường nào là bắt buộc.

Một số điểm cần chú ý

  • các view được khai báo trong controller sẽ được khởi tạo sẵn. Tôi bẫy sự kiện active của photosearch để xóa các kết quả search cũ khi màn hình này được active
  • alias được dùng để truy cập view từ controller
  • Ext.widget sẽ tạo ra instance mới – đừng hiểu nhầm đó là cách tham chiếu đến view.


Kết luận

ExtJS là một framework rất tốt để xây dựng các ứng dụng Rich Internet, đồng thời cũng là đối thủ nguy hiểm của Flex. Nếu bạn theo dõi blog của tôi từ trước, bạn có thể dễ dàng thấy tôi đang sử dụng ExtJS để thay thế Flex 🙂