Building a custom front-end to ACS using Node.ACS [Part 2]

3d abstract architecture background

On my previous post we went through the process of setting up a Node.ACS app, and understanding the basics of its built-in MVC framework. It’s now time to integrate ACS back-end services. Our main goal for this mini-project is to use a responsive framework (Bootstrap) to provide a custom, clutter-free front-end for ACS. Think about it this way: You’re using ACS to store locations. Why give your client access to ALL of ACS, just to curate data? ACS’ interface is designed for the developer, not for the end-user. We’ll build a phone and tablet-friendly web user interface what will allow them to easily enter data into the system. So let’s get started!

Structure of our website:

We’ll have a Login screen that will be used to login against the ACS User service. Upon successful login, the user will see a screen displaying a list of places that will be part of the ACS Places service. This screen will provide options for Adding and Deleting places, as well as launching a “Google Map” when a location is clicked. On the top navigation area we’ll have two links, About and Contact with sample content only to illustrate linking and session management. The website will look like this:


In this file you initialize your website and your session with ACS.

var ACS = require('acs').ACS;

// initialize app
function start(app, express) {
     app.use(express.favicon(__dirname + '/public/images/favicon.ico'));          //set favicon

     // this line is explained @
     app.use(express.session({ key: 'node.acs', secret: ACS_SECRET }));



    { "path": "/", "callback": "application#index" },
    { "path": "/error", "callback": "application#error" },
    { "path": "/home", "callback": "home#home" },
    { "path": "/login", "method":"post", "callback": "useraccess#login" },
    { "path": "/logoff", "callback": "useraccess#logoff" },
    { "path": "/about", "callback": "application#about" },
    { "path": "/contact", "callback": "application#contact" },
    { "path": "/api/delete", "callback": "api#deleterec" },
    { "path": "/api/addplace", "method":"post","callback": "api#addrec" }
    {"path": "/home", "callback": "session_filter#validateSession"},
    {"path": "/about", "callback": "session_filter#validateSession"},
    {"path": "/contact", "callback": "session_filter#validateSession"},
    {"path": "/api/delete", "callback": "session_filter#validateSession"},
    {"path": "/api/add", "callback": "session_filter#validateSession"}
    { "event": "", "callback": ""}

This file is in many ways the heart of your app. Here you define how the user is allowed to interact with the website, or how a page should interact with another. The first section, the routes, are a fundamental part of an MVC website. Defining this section is part of your website planning process and provides you a clear idea of how your website will behave.



I have stored functions in different files, but only for organization purposes. This is more an issue of your personal programming style. You can certainly use a single file for all your functions. This table should be read like: When the user browses to /home, I will execute the home function inside /controllers/home.js and the data will be available via GET.

Now let’s look at the filters section, which has a similar format.


All entries are using the same function inside the same file. This block is actually providing a way for us to protect certain areas of our website. Instead of having to validate the user session by code on every page, we set a filter on the pages we want to protect. The validateSession function simply verifies the validity of the session. If invalid redirects to error page, if valid, control is returned to the page controller.

function validateSession(req, res, next) {
  if(!req.session.session_id) {
  } else {


Access to ACS methods is consistent with the way you’d used them with Titanium, where you call the method and pass an object and a callback.

For our login method, we grab data from the HTTP POST and then send to ACS.

function login(req,res){
        // grab data from http post
        login: req.body.username,
        password: req.body.password
    }, function(data) {
    	if (data.success){
    		// set session data to be used later througout the app
		req.session.fullname=data.users[0].first_name + ' ' +
                // the "home" controller will pick it up

When the user successfully logs in, he/she is taken to Home, where a list of Places is displayed. The controller for the “Home” template looks like this:

function home(req, res) {
        order: "-created_at" // new on top
    }, function(data) {
        if(data.success) {
            res.render('home', {
                                title: 'Beer Places',
        } else {
            res.send('Error occured. Error code: ' + data.error + '.
Message: ' + data.message);

The line that reads res.render(‘home’,{}) is sending some data to the View, and one of these pieces is the actual places array that was returned by ACS. This Array is send as a static, client-side array to the view. The templating engine can now loop through the array and write the rows in HTML.

<% places.forEach(function(place){ %>
  <tr id="<>">
    <td><a href="<>@
<%=place.latitude%>,<%=place.longitude%>" target="_blank"
    <td><a href="javascript:void(0);" onClick="deleterec('<>')"
title="Delete"><div style="text-align: center">
<i class="icon-remove-circle"></i></div></a>
<%    }) %>

If you look closely, you’ll see that the places array effectively is available to the template. Also notice that you can execute Javascript code by encapsulating it in tags, in this case performing a forEach loop on the Places array, and displaying HTML rows. Just remember, when you want to execute Javascript code you use <%= your_code %> and to echo values you use <% your_variable %>.

An API on top of an API

You could use Node.ACS to provide high-level methods, an API if you like, that interact with the ACS API. An example of this technique is providing a “delete” method that in turn will call the ACS delete place method. Why do this? Well, for one, you don’t want to have your API key available in your Javascript source. With this method, your API key resides inside Node.ACS, that is in the server-side. Another reason could be because you’d like to perform other operations with the data returned by ACS, perhaps even return a new JSON string to your front-end. If you look at our Javascript code for deleting a record, it looks like this:

function deleterec(recid){
      var r=confirm("Delete this record?");
      if (r==true){
            url: '/api/delete/?id=' + recid,
            type: 'GET',
            success: function(data) {
            error: function(XMLHttpRequest, textStatus, errorThrown) {
                //alert("Status: " + textStatus);
                //alert("Error: " + errorThrown);

NOTE: In a real-world scenario you’d want to provide a more secure way of deleting your records and not by simply calling a Delete URL with your record id, but those security measures are out of the scope of this post.

Using Node.ACS’ built-in is really fun. The fact of not having to install a web server is a very convenient feature, and being able to take advantage of node.js definitely provides virtually endless possibilities.

The full source code for this example is available at, simply fork/clone, add your own ACS Key and Secret, and hack away. This is a sample/proof-of-concept so feel free to send me pull request with error corrections or features you’ve added to the project.


  1. […] Building a custom front-end to ACS using Node.ACS [Part 2] […]

  2. Hi Ricardo,
    I would like to know if Appcelerator provides any database service. You had used to create a database account in response to my previous question (Part-1 post). Obviously external providers means additional concerns about scalability / reliability.


Comments are closed.