Monday, June 9, 2014

AngularJS: Adding new objects with Restangular

Restangular allowed us to define models for our application that are automatically generated for us as we load the data from our API. However, we ran into a small problem when posting new objects in our app as these were not originally loaded through Restangular, and thus, were just plain old JavaScript objects, and not objects created through our model. Lets take a look!

The problem

Imagine our app to be a typical users CRUD page where we show a list of users - and we can add, edit, and remove these users. The API has a users endpoint that provides us the basic CRUD operations that we need.

Let's say that as part of our model we want to compile the full name of the user. So we add a fullName method to our model:

Restangular.extendModel('users', function(model){

 model.fullName = function(){
  return this.firstName + this.lastName;
 };

 return model;
});

So far so good. We can load our users, Restangular will automatically add a fullName method to each user object. Let's say we are displaying these users in a simple html view by setting the users property in our scope.

<div ng-repeat="user in users">
 <span>{{user.fullName()}}</span>
</div>

Nice! This works as expected, but what happens when we would like to add a new user. Normally, we could simply add a plain old object to the collection of users, but what about our new fullName method? We need to make sure that as we dynamically add new users, we somehow provide to each user object, all the methods defined in our model.


Restangular.all('users').getList().then(function(users){
 $scope.users = users;
});

...

var newUser = { firstName: 'first', lastName: 'last' };
$scope.users.push(newUser);

$scope.users[$scope.users.length - 1].fullName() // Error - this object does not have a method called 'fullname'

The solution

Luckily, Restangular has the flexibility to allow us to do just that. Let's take a look at the code

Restangular.extendCollection('users', function(collection){
                                                … 
  collection.add = function(userData){
    var user = Restangular.restangularizeElement(this.parentResource, buildData, 'users');
    this.push(user);
  };
 
  return collection;
});

Apart from adding new method to our models, Restangular also provides us with the capability of adding new methods to our collection of models with the extendCollection method. This collection would be the result of calling the Restangular method getList to load a list of users. Please refer to the documentation for more information on loading data with Restangular.

This new add method uses the Restangular.restangularizeElement method that builds a model with the data we provide as if Restangular was loading the data for this user from an API call. This built model will have our fullName method. We can then proceed to add the new user object to the collection itself.


Restangular.all('users').getList().then(function(users){
 $scope.users = users;
});

...

var newUser = { firstName: 'first', lastName: 'Last' };
$scope.users.add(newUser);

$scope.users[$scope.users.length - 1].fullName() // 'First Last'

Conclusion

Admittedly, this is a very simple solution, for a simple problem, but I could not find any good documentation online on the recommended way to handle this particular case with Restangular. I hope this blog post proofs to be useful, and it saves somebody the need to dig through the Restangular documentation and/or code. Let me know if you have a simpler solution to this problem!

Monday, March 3, 2014

Sending and Receiving Email using Mandrill

This post will show you how your NodeJS app can send and receive emails using Mandrill. It will show you how to setup the emails you send so that when your users reply to those emails, your application can process those replies.

The trick to receive emails is to send the initial email with a unique reply-to email address. That way, when the user replies to the email, your app will use that unique email address to process the message.

For the examples in this post, the reply-to email address will look like reply-123@replies.sampleapp.com, where 123 is the unique id of some object in your app. We use reply- in the email address because that lets us setup a route in Mandrill that matches email addresses that starts with reply- followed by some id. The mandrill documentation tells you how to setup that kind of route, see section Adding Routes in Mandrill's Inbound Email Processing Overview.

Thus, when your app receives an email from reply-123@replies.sampleapp.com, your app will know that the contents of the email belong to object with id 123. And from there you will apply your specific business requirement.

Monday, February 24, 2014

Development Grunt Tasks in a Heroku Production Environment

We ran into a bit of a conflict between Gruntfile.js and package.json. The package.json file defines the npm packages that are used by the application and by Grunt. However, some of the grunt tasks only make sense to run in a development or test environment, but not in a production environment. Our package.json file was able to make this distinction but our Gruntfile.js wasn't.

Thursday, February 20, 2014

Angular JS localization with Require JS i18n module

When we started working with AngularJS, one of the first non-trivial challenges we were faced with was to find a way to localize the text in our app.

We had a few basic requirements for the localization solution:

  1. Will not require any changes to my existing controllers.
  2. Will not polute the current $scope.
  3. Be able to define the desired string directly on the markup with a simple syntax.
  4. Be defined as a module that can be minified and compiled with RequireJS.

Friday, February 7, 2014

Complete Grunt deployment workflow for a client side app with RequireJS, Jasmine, LESS, and Amazon S3

This blog post will cover a complete Grunt workflow for a client side app with RequireJS. There are no server side components, and the data is retrieved through a web service API. The goal for this post is to cover all the different steps for a full Grunt build script with the goal of a complete release package that can be deployed to any environment - in this case, we are deploying to an Amazon S3 bucket.

For this post, we assume some experience of working with Grunt. We will not cover all the different options in the plugins we use, but there will be links to all the plugins for further documentation and reference.

What will we cover?

  • Code check with JsHint.
  • Unit test execution with Jasmine.
  • Compilation and minification of JavaScript files
  • Compilation and minification of LESS files to CSS.
  • Asset management to ensure proper cache functionality
  • Environment configuration by setting environment specific variables.
  • Versioned package ready to be deployed.
  • Deployment of our files to an Amazon AWS S3 bucket.

Let's start!

Wednesday, April 3, 2013

Recognizing user exit with Socket IO

In Dobly we needed to keep track of which users are currently active. Since Dobly uses Socket IO, I knew I could leverage the disconnect event, but by itself it took several seconds to fire after the user had left, so it wasn't enough by itself - I needed it to fire exactly when the user had left (move to another page, or close the browser or tab).

Recognizing when the exact moment when a user leaves your application can sometimes be tricky. Usually it requires handling the unload event. Many people recommend using the beforeunload event, but I've found that to be inconsistent as you move across different browsers and operating systems. Luckily, Socket IO was there to help.

var socket = io.connect(, {
'sync disconnect on unload': true });

This configuration will indicate to Socket IO to call your disconnect event on browser unload. With this set you don't need to worry about which event do I need to bind for this browser or that. It takes care of all that for you and works consistently across the different browsers.

Hope this helps!