Developing a mobile app with Phonegap, AngularJS and ExpressJS Part I

As a side project, I have embarked lately on the task of developing a mobile application with what ended up using Phonegap, AngularJS and ExpressJS. The gist of the application is to allow users to sign up and be able to share financial tips. I will document my journey along for others who are thinking of travelling down the same road, starting with my choice of technologies, this being my first attempt at building up the whole architecture from the ground up and since I am a front end developer and I wanted to leverage that experience to build a mobile app instead of going native.

Why PhoneGap and AngularJS and not Sencha Touch or Titanium?

When deciding on the initial approach to building the app, I initially thought about using Sencha Touch. I had tried Titanium before but had found it unwieldy although I like the whole integrated IDE to production setup. I work with ExtJS on a daily basis so I figured Sencha Touch would be a natural complement but after working with AngularJS, I really did want to keep getting better at it and not have to duplicate my learning by both doing Angular and Sencha Touch at the same time so i settled on PhoneGap after reading this tutorial (must read, you need to also read this here ). My time outside of work is very limited so I have little patience for frameworks with a high learning curve. I love working with AngularJS and adding Yeoman to the mix just makes it a breeze to work with so I was set on my front end tools.

Why ExpressJS?

When deciding of what framework to use for my API I initially tried Laravel, a PHP Web framework I had heard good things about it and it did not dissappoint. With the right instructions, the set up was a breeze and I had a basic API setup quickly. I liked the overall organization of the framework but at this point, I spend 90% of my time writing Javascript, so again, I wanted to stay within a single frame of mind for this project. I had always looked forward to finally trying out NodeJS , so server side Javascript it was. Given its nature, NodeJS can be unsettling because you are basically writing your own webserver, and coming from a background where you had to deals with the Apaches and Tomcats, it takes a little while to accept that new paradigm. Freedom can be overwhelming and I needed some structure to this whole new tool so I dug up ExpressJS, which is a web application framework for Node. I also decided to use MongoDB for my database, so I needed to find out how to make ExpressJS and MongoDB work nicely together, and Moongoose provided a good abstraction for interaction with my MongoDB database. Overall understanding the ExpressJS architecture, the concept of routes and middleware was the most challenging part of this part of the journey. I ran into Locomotive and I am not so far along that I can’t refactor using it as it adds convention over configuration.

API, API, API…

This is my first time building out a RESTful API as opposed to just using and it brought up considerations that I briefly wondered about before, the first one being how do I protect my API since this will be a closed system, I just want my mobile app to talk to my API. As a front end developer, those are considerations I never thought that deep on. I had to consider each strategy (Basic and Digest Authentication, API Key, OAuth, OAuth2), and how it would affect my implementation in AngularJS as well. This is the part that to a degree I am still pondering about but I am not letting me stop from moving forward.

Yeoman

Starting up was easy following Brian’s Ford instructions, I actually use Eclipse as an IDE where both my PhoneGap project and ExpressJS applications reside. There is a NodeJS plugin that exists for Eclipse that I use to run my API server initially but then I found Nodemon, which monitors my app for changes and restarts the server automatically. All of my Angular code resides in the assets folder of my PhoneGap project where I instantiated my Angular project using the yo angular generator. If you have not used Yeoman before to manage your web development projects, I strongly recommend it.

I create all my controllers, directives and services through the yo command as it also creates the proper accompanying unit tests. One small tip here, you might be wondering where yo gets the name of your app from when creating the angular module for your application and how to modify it so that you don’t have to keep changing the app name every time you create a new file? Change the “name” property in your bower.json file and yo will use a concatenation of that name and the “App” suffix to name your Angular modules.

AngularJS & Mobile Development Libraries

I am using Angular 1.1.5  as it adds a angular-mobile resource which adds better support for click events on mobile devices.  I initially thought of using Jquery Mobile even though I had a lot of apprehension about its speed but my app won’t be doing anything fancy UI wise, just presenting and collecting information. There is a plugin called the JQuery Mobile Angular Adapter which allows the two libraries to work nicely together but I could not get it going from the routing point of view, I was trying to do my application routing through AngularJS and it just was not playing nice, maybe due to my ignorance so I gave up on it and decided to stay entirely in AngularJS . I decided though to make use of the Angular Mobile Nav plug-in for my main screen and it worked as expected right out of the box with little configuration. There is though a promising project integrating JQuery Mobile and Angular called Angular JQM which instead of using adapters for JQuery mobile provides native Angular directives for JQuery Mobile, removing the need for the 3rd party libraries. As far as development itself it’s your typical Angular app so nothing new there.

NB: Doing bower install angular will get you the latest stable branch, to get the unstable branch you need to point Bower configuration for Angular dependencies to Pattern Consulting bower repo. This is what my bower.json looks like:

{
 "name": "appMobile",
 "version": "0.0.0",
 "dependencies": {
 "angular": "PatternConsulting/bower-angular#1.1.x",
 "json3": "~3.2.4",
 "jquery": "~1.9.1",
 "bootstrap-sass": "~2.3.1",
 "es5-shim": "~2.0.8",
 "angular-resource": "PatternConsulting/bower-angular#1.1.x",
 "angular-cookies": "PatternConsulting/bower-angular#1.1.x",
 "angular-sanitize": "PatternConsulting/bower-angular#1.1.x",
 "angular-mobile": "PatternConsulting/bower-angular#1.1.x",
 "angular-bootstrap": "~0.4.0",
 "angular-ui": "~0.4.0"
 },
 "devDependencies": {
 "angular-mocks": "PatternConsulting/bower-angular#1.1.x",
 "angular-scenario": "PatternConsulting/bower-angular#1.1.x"
 }
}

Another gotcha is that when trying to deploy your PhoneGap app to your phone or emulator for testing in Eclipse, you might run into an AAPT error such as:

"[2013-07-16 01:20:35 - appmobile] /projects/appmobile/assets/app/bower_components/angular-cookies/docs/partials/api/ng.directive:a.html: error: Invalid filename.  Unable to add."

This is because of the dot in the file name. Simple solution is to delete the “docs” folder in all your angular-* folders under bower_components.

Design

I have absolutely zero design skill so of course I am using Twitter Bootstrap, and the plan is to have a designer spruce it up once development is complete. One thing I have noticed is that I find the height of text inputs to be too small. Holly Schinsky in her excellent introductory article mentioned Topcoat which I had never heard of before, and it looks good so who knows, I might give it a run on a feature branch.

Summary

The process has been interesting to say the least, and it leads sometimes to second guess myself but that is the process of learning. I will keep up updated as of my progress, issues and findings in subsequent posts.

Advertisements

26 thoughts on “Developing a mobile app with Phonegap, AngularJS and ExpressJS Part I

    1. What’s your stack like? You can’t use all of them within a single project. I have PhoneGap and AngularJS in one project and my API is written with ExpressJS as a separate project

  1. Ok, I will seperate this. All client code goes to www in phonegap app?

    Whats then config.json of phonegap app, so that it uses index.ejs in www/views/index.ejs, or do I have to do this another way?

    1. You are overthinking it I think. ExpressJS does not render your view, it’s just a Restful API at least in my case. All of my views are in the AngularJS app which is loaded in the index.html file that will be in the “www” folder. PhoneGap works by rendering your code in a WebView, so that index.html will be rendered by the browser and load your application.

  2. Ok I understand, I was using express to render my views. But I still have no success with connecting my client with my expressjs server.

    Do I have to modify config.json, or am I missing something?

  3. When you mean connecting , what do you mean exactly? Basically once you separate your ExpressJS app and your PhoneGap app, they are two separate entities. Think of it as your client code trying to talk to the Twitter API (which would be your ExpressJS API). One gotcha is that now any ajax call from your client app to your API will be considered crossdomain, so you have to enable CORS on your ExpressJS app, which is easy to do: refer to the code here
    http://enable-cors.org/server_expressjs.html
    That might be your issue. Once that’s set up, try to set up a simple route in you client app that returns for example OK and see if you can access that.

  4. Thank you, I used this code in my expressjs, but still no luck, my app still does not connect with my web server.

    app.use(‘*’, function(req, res, next) {
    res.header(“Access-Control-Allow-Origin”, “*”);
    res.header(“Access-Control-Allow-Headers”, “X-Requested-With”);
    next();
    });

    I have the feeling like the app is not connected with the server.
    I think I have to put somewhere in my phonegap app the information of my server, but dont know where?

  5. I figure it out. Because before I had everything in one app, my http requests were like this

    http.get(“/account”, ….)

    now

    http.get(“http://url.to.website/account, …. )

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s