Yesterday, we introduced Mobile Packs designed to make it easier and faster for you to create mobile apps on the Salesforce platform. I had the distinct pleasure of working with the AngularJS collection of sample apps, along with Raja Rao DV and Dave Carroll, and today I’m going to walk you through how they work. If you’d like to get these up and running and try them out, here are step by step instructions.

AngularJS and Salesforce Architecture

The AngularJS Mobile Pack includes three flavors: Visualforce, Node.js and PHP. All three use the same basic app. AngularJS provides the core application structure, Bootstrap provides the styling and responsive design features and forcetk.js handles the integration with our REST API. The Node.js and PHP samples include an additional feature, a proxy, which is critical to managing the same origin policy browsers enforce with client side features like Javascript.

AngularJS offers a very interesting approach to building an HTML based webapp. Once you import the AngularJS library, you can connect it to any HTML element by simply adding AngularJS attributes to a tag or by setting the class attribute for a tag to an AngularJS CSS class. (You can read more about bootstrapping your AngularJS app here.) AngularJS then handles the rest, including routes, dependency injection and HTML templates.

The sample app has several key components.

* index.php / index.html — This primary file defines the basic app container and links all of the required external resources.

* app.js — Defines the routes users can take through the app, the controller functions for each of the routes and the HTML partials AngularJS will inject into the main template.

* forcetk.js — The REST api toolkit adapter for Javascript (Github)

* Angular-Force.js — The glue layer between AngularJS and forcetk.js (Github), including an AngularForceObjectFactory that provides a model for specific Salesforce object types (standard and custom).

* forcetk.ui.js — An authentication layer that interacts with Salesforce Identity services to manage OAuth2 interactions and maintain login information.

* Bootstrap — The great open source CSS framework from Twitter provides styling and the responsive web design framework that helps your apps look great regardless of the user’s device type.

* jQuery — Required by the forcetk.js library. jQuery and AngularJS play very well together. As a side note, it should be possible to rewrite forcetk.js to rely only on AngularJS features, so if you’re looking for a weekend project there you go.

Finally, there are two proxy options to use depending on your host operating system. Each sample already includes the correct proxy. For example, if you are using PHP, your app will use “proxy.php”. If you are deploying to a Node.js environment, your proxy will be handled using the '/proxy/?*' setting of the Node.js sample app. If you are deploying your app as part of a Visualforce app using a package, no proxy is required as there are no same origin policy related concerns.

Sample Use Case: Contact Management

Our basic use case is simple: provide a way for someone to authenticate with Salesforce and work with their contacts. This includes a basic list, search and full CRUD operations. (I’ve shortened the code examples here for clarity. You can click on full source for a link to the appropriate file on Github.)

In app.js, we start by defining routes. (Full Source).

app.config(function ($routeProvider) {
$routeProvider.
when('/contacts', {controller: ContactListCtrl, templateUrl:  'partials/contact/list.html'}).
otherwise({redirectTo: '/'});
});

This route says that if the URL ends in “/contacts”, Angular should use the ContactListCtrl and display the results using the “list.html” partial.

App.js also instantiates the Contact object based on the AngularForceObjectFactory. This Contact object is then fully injectable into all of the controller methods used by the app.

angular.module('Contact', []).factory('Contact', function (AngularForceObjectFactory) {
var Contact = AngularForceObjectFactory({type: 'Contact', fields: ['FirstName', 'LastName', 'Title', 'Phone', 'Email', 'Id'], where: '', limit: 10});
return Contact;
});

Next, we define the controller methods. There are lots of interesting controller methods, but let’s start by looking at just one, the ContactListCtrl.

function ContactListCtrl($scope, AngularForce, $location, Contact) {
  //variables and methods....
}

In the function declaration, you can see that we depend on AngularJS to inject four things. These are injected automatically, and their order in the argument list is not important.

$scope is the AngularJS variable that maintains the app model across the application.

AngularForce is the connector that lets Angular JS use forcetk.js.

$location is an AngularJS service that helps manage browser location information, including both current location and redirection.

Contact is the app.js defined object representing the Contact data model.

Controllers themselves are pretty simple. There are variables, $scope.searchTerm for example, and functions like $scope.doSearch(). Let’s take a look at $scope.doSearch() (and be sure to stay tuned for a note on separation of concerns in a moment).

function ContactListCtrl(AngularForce, $scope, Contact, $location) {
$scope.searchTerm = '';
$scope.doSearch = function (searchTerm) {
Contact.search(function (data) {
$scope.contacts = data;
$scope.$apply();
}, function (data) {
}, 'Find {' + escape($scope.searchTerm) + '*} IN ALL FIELDS RETURNING CONTACT (Id, FirstName,
LastName, Title, Email, Phone, Account.Name)');
};
}

Notice that both variables and functions are attached to the AngularJS provided $scope variable, ensuring they are always available to the framework. This being Javascript, it is very simple to modify the $scope object in any way we see fit. In this case, $scope.doSearch() calls the Contact search function with a success and failure callback as well as a customized query string. Note the $scope.$apply(); call in the success callback. This is very important. The explicit call to $scope.$apply(); propagates the data changes that happen when we get results from our SOSL query back from forcetk.js, which uses jQuery outside of the AngularJS framework. (Note that although I used SOSL in this example, you can of course use SOQL just as easily.)

And now, a note about separation of concerns. You’ll notice that this example explicitly includes a SOSL query in the controller, despite the fact that MV* apps generally avoid this. You can see in the Node.js sample, for example, where this is refactored into the AngularForceObjectFactory. In my opinion both are valid approaches which enable different things. Encapsulating all of your query terms into AngularForceObjectFactory improves testability and narrows the code in the $scope.doSearch() function to a bare minimum set of callbacks representing success or failure. However, including the SOSL and the target fields in the controller imcreases your flexibility around which set of fields you want to return and how you want them ordered. In the end, the right way to do this is a decision you need to make for your app. Angular JS is flexible enough to let you make this choice in a way that works for you.

The last piece I want to cover is the HTML partial that displays the results of this controller and route combination. I’ll focus on one illustrative section of the “list.html” file, you can see the full source here.

<table class="table">
<tbody>
<tr ng-click="doView(contact.Id)" ng-repeat="contact in contacts">
<td>{{contact.FirstName}} {{contact.LastName}}, {{contact.Account.Name}}</td>
</tr>
</tbody>
</table>

If you look at the “<tr>” section, you’ll see two Angular JS attributes, ng-click and ng-repeat.”ng-click” defines which of the ContactListCtrl functions will execute when a user clicks on the row. “ng-repeat” iterates over a collection variable, $scope.contacts, and assigns each current value to the contact variable. In the “<td>” section, you’ll see where we access the contact variable using {{variable.attribute}} notation. I loved using this incredibly compact syntax.

Next Steps

If you haven’t already, I highly recommend going through the AngularJS sample apps. If you haven’t touched Javascript in a while, you will be pleasantly surprised at how easy it is to use this framework once you get the hang of it. And if you haven’t used Heroku as a deployment point for apps, you’ll be amazed at how easy that is, too.

If you have questions, please feel free to comment here or on contact me Twitter. I’d love to hear about your experience with these samples!

 

tagged , , , , , Bookmark the permalink. Trackbacks are closed, but you can post a comment.
  • http://twitter.com/donrobins Don Robins

    Great sample apps, I particularly like the Angular version as I had not seen the framework in action. Really like the leverage of the Bootstrap functionality to hide and show different DIVs (pages) responsively for the device. I was digging in this morning trying to find what I assumed was a media query that changed the display as I shrank the browser window, and looking at the and . Now I have to see if they have similar classes in the CSS for tablet. Very nice work on the ref apps, (not to mention the easy deployment package!.)

    • http://twitter.com/ReidCarlberg Reid Carlberg

      Great to hear Don. Bootstrap is really interesting. I feel like I’ve only scratched the surface.

    • http://twitter.com/ReidCarlberg Reid Carlberg

      Great to hear Don. Bootstrap is really interesting. I feel like I’ve only scratched the surface.

  • Phil

    Good stuff! Anxious to try it out. If this was implemented using VF remoting instead of the forcetk library jQuery would be unneeded correct?