Node.ACS Tutorial 1: PixGrid photo uploader

Fast speed dataflow.

After launching the Node.ACS developer preview 2 last week, we are excited to share with you some real examples of how to write a kickass Node.ACS app that connects to ACS as the data backend. We’ll be sharing several more examples in the coming weeks.

Today I want to walk through a sample Node.ACS app called PixGrid which lets users signup, login, upload and view photos from a web browser. It uses ACS as the data backend to store user data and photos. You can download the source code from Github.

PixGrid is built on Node.ACS’s easy to use MVC Framework. In this app, the M(model) is ACS. We want to let ACS handle all the data storage and only focus on the application logic and view in the Node.ACS part.


This is one of the entry points of Node.ACS MVC framework projects. This file defines all the routing and filtering logic for the app.

PixGrid Routes

  • Signup
    • { “path”: “/signup”, “method”: “get”, “callback”: “application#signup” }
      This method renders the signup page
    • { “path”: “/signup”, “method”: “post”, “callback”: “user#signup” }
      This method performs the actual signup with ACS
  • Login
    • { “path”: “/login”, “method”: “POST”, “callback”: “session#login” }
      This method performs actual login action with ACS
    • { “path”: “/login”, “method”: “GET”, “callback”: “application#login” }
      This method renders the login page
  • Logout
    • { “path”: “/logout”, “method”: “get”, “callback”: “session#logout” }
      This method performs a call to ACS to logout a user
  • Photo view (query)
    •  { “path”: “/”, “method”: “GET”, “callback”: “application#index” }
      Display login page if a user is not logged in, otherwise, display photos uploaded by the user
  • Photo create
    • { “path”: “/photos/create”, “method”: “post”, “callback”: “photos#_create” }
      Upload a photo to ACS by selecting a photo file
    • { “path”: “/photos/create.json”, “method”: “post”, “callback”: “photos#_create_json” }
      Upload a photo to ACS by ajax drag and drop (only works on Chrome and Firefox)
  • Photo delete
    •  { “path”: “/photos/:id/delete”, “method”: “get”, “callback”: “photos#_destroy” }
      Delete a photo from ACS
  • Page not found
    • { “path”: “*”, “method”: “get”, “callback”: “application#page_not_found” }
      Render a page not found for everything else


PixGrid Filter

In PixGrid, most pages require a user to be logged in, so we put a checkUserSession filter to all pages

  • { “path”: “/”, “callback”: “session_filter#checkUserSession” }
    Inside the checkUserSession method, it bypasses /login, /logout and /signup


app.js is another entry point of Node.ACS MVC framework projects. It initializes the ACS and configures express, which is included in the MVC project by default. Please make sure to update the following line in app.js to fill in your own ACS oauth key and secret.


ACS user sessions

When writing apps for devices,  it is common to keep user specific information on the device and use it later because only one user can use your app at a time, however, the same code will not work well if it is running on a server because the code would be shared by multiple users.

Use photo upload as an example. If you save an uploaded file to a temp file on your Node.ACS server before sending it to ACS, you need to make sure the filename is unique for each transaction so they won’t get overwritten. For example, if user A uploads a photo to your Node.ACS server, your code stores it as photo.tmp, before the server gets a chance to send this photo to ACS, user B uploads another photo and your code will overwrite user A’s photo.tmp if you choose  to use the same tmp filename.  Check out photo.js method _create_json to see how it handles a file drag and dropped by AJAX calls.

The same goes to ACS user sessions, it is tempting to store an ACS user session on Node.ACS server for subsequent calls. But this session will get overwritten when another user logs in to ACS through the same Node.ACS server. That’s why ACS module for Node.ACS provides additional parameters (req,res) to let you pass through a user session cookie without the need to store it on the server.

    login: req.body.un,
  }, function(data) {
     // handling login callback
  }, req, res);

It is important to pass the req and res to ACS library so that it will pass along or set the cookies if needed. In the login case, it will set the ACS server returned cookie in res which will be passed back to your device. Most device handles cookies automatically so you don’t need to do anything extra on the device.

Subsequently, the photo upload call will take the cookies stored passed along by the device to ACS.

ACS.Photos.create(data, function(e) {
    if(e.success && e.success === true){
      req.session.flash = {msg:"Successfully create a photo #"[0].id, r:0};
      req.session.flash = {msg:e.message, r:0};
  }, req, res);

As long as you keep this key difference in mind, you can use almost the same code that communicates with ACS in both Titanium and Node.ACS.

Please use Node.ACS google group if you have any questions.


  1. […] DevCenter Posted this Node.ACS Tutorial 1: PixGrid photo […]

  2. Hello Experts

    I am trying to build a front end to my ACS database. As a part of the admin front end, users will upload images and I am using Photos object to save them. I am using following code to upload the photos to cloud db and it works like a charm on my local system.

    var data = {
    photo: req.files.photo_file
    data[‘photo_sizes[medium_500]’] = ‘500×333’;
    data[‘photo_sync_sizes[]’] = ‘medium_500’;

    ACS.Photos.create(data, function(e) {
    if(e.success && e.success === true){
    // Update custom object with this photo
    fields: {[0].id,[0].urls.medium_500
    },function(data) {
    if(data.success) {
    // console.log(‘Updated successfully:’ + JSON.stringify(data));
    }else {
    console.log(‘Error:\n’ +
    ((data.error && data.message) || JSON.stringify(data)));
    logger.debug(‘Error: ‘ + JSON.stringify(e));
    req.session.flash = {msg:e.message, r:0};

    But when I publish the app to the as Node.acs service, while uploading the images, app crashes. Running the “loglist” command produced following output.

    [ERROR] [1233] Error: EACCES, open ‘/tmp/292fb15dcab44f58a315515bd9e70a8a’

    This is the path that HTML form sends from the client as part of the form data that contains the file input. Please let me know how to solve this issue.

    Thanks and Regards,


Comments are closed.