Retrospective: Angular JS and Rails at Rivalry

Presented by Tejus Parikh, CTO and Co-Founder

Introduction

Rivalry is built with AngularJS and Rails. We provide analytics, reports, and (most importantly) allow sales managers to coach their sales reps.

Our application has to be easier and more useful than Salesforce, email, and spreadsheets.

The speaker

CTO and co-founder of Rivalry

Relevant Experience

  • 10-ish years doing UI/UX
  • Flex development at WeTheCitizens
  • Web framework developer at Appcelerator
  • Flex and Vaadin development at Vertical Acuity

Structure

  • Overview of AngularJS and Rails
  • Angular: Good, Bad, Ugly
  • Our future with it

Rivalry's Architecture

Why Rails?

  • We knew how it worked
  • Good libraries for connecting to SFDC
  • Super easy

Why AngularJS?

  • Front end interaction was the selling point
  • Good community
  • New Toy

How we use AngularJS and Rails

High level view

Skip some of the basics (adding scripts, adding css, etc)

Don't fret, there are easier ways to get started

Unfortunately...

Set ng-app

You'll need one *.erb


<html>
	<head>
	...
		<%= csrf_meta_tags %>
	</head>
	...
	<body ng-app='rivalry'>

	</body>
</html>
						

Create the Angular App


(function() {
	var module_deps = ['ngRoute', 'ngResource', ...];
	var rivalry = angular.module('rivalry');

	rivalry.config(['$httpProvider', providerInitFunc]);

	function providerInitFunc($httpProvider) {
	    /* include the rails CSRF token when making AJAX calls */
	    $httpProvider.defaults.headers.common['X-CSRF-Token'] = 
	    	$('meta[name=csrf-token]').attr('content');
	}
});
						

Add a view container


<html>
	...
	<body ng-app='rivalry'>
		<div ng-view></div>
	</body>
</html>
						

Create a route

ngRoute is the official router

There are alternatives under active development


.when('/', {
	controller:  'DashboardCtrl',
	templateUrl: '/assets/home/dashboard.html'),
	activeTab:   ['home', 'dashboard'],
	reloadOnSearch: true
})
						

Create View

Create a file /assets/home/dashboard.html


<h2>Hi there {{user.name}}</h2>
						

Create Angular Controller


(function(module) {
	var ctrldef = ['$scope', 'User', DashboardCtrlFunc];

	module.controller(ctrldef);

	function DashboardCtrlFunc($scope, User) {
		$scope.user = User.get({'id': user.id})
	}
})(angular.module('rivalry'));
						

Just a few more steps

Create the User Angular Factory


(function(module) {
	var userdef = ['$resource', UserFunc];

	module.factory('User', userdef);

	function UserFunc($resource) {
		var params = {'id': '@id'};
		var commands = {'update': {'method': 'PUT'}};
		return $resource('/users/:id.json', params, commands);
	}
})(angular.module('rivalry'));
						

Create user model and route

Handwave, it's done!

Rails Controller


class UserController < ApplicationController
	load_and_authorize_resource :user

	def show
		respond_with @user
	end
end
						

All done!


{{user.name}}
						

Gets automatically templated


Tejus Parikh
						

What have we learned

Both the good, the bad, and the ugly

AngularJS

Here are some of the features we really find awesome

Independent Presentation

Control logic is markup independent

Can reuse views and controllers independently

Directives

Directives are like JQuery Plugins on Steroids



						

Directives

Directives

Controllers

Encapsulate and reuse code


  • {{someCalculatedValue()}}
  • 
    function UserItemCtrl($scope) {
    	$scope.someCalculatedValue = function() {
    		return doSomething($scope.user);
    	}
    }
    						

    Server Communication

    
    $scope.user = User.get({'id': user.id});
    $scope.user.$update(successCallback, errorCallback);
    						

    Reactive (sometimes)

    Especially nice for manipulating lists

    Deep Linking

    ngRoute and it's alternatives allow for linking into the app

    We use this within our emails

    Angular JS

    Aspects that I'm not fond of

    Recreating common interaction

    Loading or no data? How do you tell?

    Reactive (sometimes)

    
    Hey there, {{user.name}}, are you bored?
    						

    Renders to this if your server is slow

    Hey there, , are you bored?
    						

    JS minimization causes hair loss

    Forget an argument, prepare for staring at a 10,000k line of JS

    Factories, Directives, Controllers

    Similar, but have different API's and usage restrictions.

    AngularJS

    Ready flamethrowers...

    WTF

    WTF - Explained

    Happens 1/20 times

    Iterator with a controller. Html includes a directive.

    Controller is trying to access a value on $scope before the directive puts it there

    The resulting undefined kills the loop

    Fixed with $timeout or $watch

    AngularJS 1.x is deprecated

    AngularJS 2.x is a massive improvement

    AngularJS 2.x is completely new api

    http://eisenbergeffect.bluespire.com/all-about-angular-2-0/

    Would we use AngularJS again?

    No

    • When the abstractions fail, they will fail in ways that are hard to fix
    • 2.0 does not exist, 1.0 guarantees a rewrite

    Not AngularJS's Fault

    A lot of Angular's problems are RIA in the browser problems

    Key Considerations

    • Re-consider if an SPA is right for our use case
    • Framework for developers, not for designers
    • Framework stability: cutting edge product > cutting edge tool

    Rivalry's Next Steps

    • Continue with AngularJS
    • Wait and see how ES6 is adopted by the frameworks
    • Piecemeal replace any non-performant front end sections

    Questions?

    Or tell me why I should love Angular

    Thank You!

     

     

    PS. We're hiring. Email tejus@rivalry.com