Working With AngularJS and Socket.io

Created by Tom Wilson / @twilson63

About Me

Tom Wilson

Jack Russell Software

Web and Mobile development for HealthcareIT

President

Github - http://github.com/twilson63

Twitter - @twilson63

What is Socket.io?

Socket.IO aims to make realtime apps possible in every browser and mobile device, blurring the differences between the different transport mechanisms. It's care-free realtime 100% in JavaScript.

socket.io

Socket IO - Protocols

  • WebSockets
  • FlashSockets
  • Long Polling

Server

            
var io = require('socket.io').listen(80);

io.sockets.on('connection', function (socket) {
  socket.emit('news', { hello: 'world' });
  socket.on('my other event', function (data) {
    console.log(data);
  });
});          
            
            

Client

            
<script src="/socket.io/socket.io.js">
</script>
<script>
  var socket = io.connect();
  socket.on('news', function (data) {
    console.log(data);
    socket.emit('my other event', 
      { my: 'data' });
  });
</script>
            
            

What is AngularJS?

HTML enhanced for web apps!

What the browser should be for dynamic web apps!

AngularJS is declarative.

Super-heroic MVW Framework

Features

  • Data-binding
  • Dependency Injection
  • HTML Templates
  • Filters
  • Directives

Data-Binding

              
  <div ng-app>
    <h1>{{title}}</h1>
    <input type="text" ng-model="title">
  </div>
              
            
Live Demo

Dependency Injection

              
function MainCtrl($scope, $http) {
  $http.get('http://jsbin.com/abaqip')
    .success(function(data) {
      $scope.repos = data;
    });
}
              
            

HTML Template

              
<ul>
  <li ng-repeat="repo in repos" >
    {{name}}
  </li>
</ul>

              
            

Live Demo

Routing with ng-view


  <body ng-app="MyApp">
    <ng-view></ng-view>
  </body>
            

$routeProvider


  angular.module('MyApp', [])
    .config(function($routeProvider) {
      $routeProvider
        .when('/', { template: 'main.html', controller: 'MainCtrl'})
        .when('/page2', { template: 'page2.html', controller: 'Page2Ctrl'})
      
    })
            
Live Demo

Filters


<input type="text" ng-model="search">
<ul>
  <li 
    ng-repeat="
     repo in repos | filter:search 
     | orderBy: 'name'" >
    {{name}}
  </li>
</ul>
            
Live Demo

Directives


<blink>Like its 1999</blink>
            

app.directive('blink', function() {
    return {
      template: '<marquee scrollamount="100%">Blink!</marquee>'
    }
});
            
Live Demo

Lets build a Real-Time App

Top Hedgehog

http://www.acuteaday.com/blog/wp-content/uploads/2010/12/baby-hedgehog-cute-201210.jpeg http://twilson63.github.io/hedgehog-practice/

Socket.io

Service

              
app.factory('socket', function ($rootScope) {
  var socket = io.connect();
  return {
    // insert on
    // insert emit
  }
});
              
            

Socket.io

Service on

              
on: function (eventName, callback) {
  socket.on(eventName, function () {  
    var args = arguments;
    $rootScope.$apply(function () {
      callback.apply(socket, args);
    });
  });
}
              
            

Socket.io

Service emit

              
emit: function (eventName, data, callback) {
  socket.emit(eventName, data, function () {
    var args = arguments;
    $rootScope.$apply(function () {
      if (callback) {
        callback.apply(socket, args);
      }
    });
  });
}
              
            

Search

Template

              
<form class="form-search">
  <div class="input-append">
    <input class="search-query" type="text" 
      ng-model="query">
    <button class="btn" ng-click="search()">
      <i class="icon-bolt"></i>
    </button>
  </div>
</form>
              
            

Search

Client Side

              
$scope.search = function() {
  socket.emit('search', $scope.query, 
    function(res) {
      $scope.hogs = res.responseData.results;
  });
};
            
            

Search

Server Side

              
var googleUrl = 'https://ajax.googleapis.com/' +
  'ajax/services/search/images?v=1.0&';
socket.on('search', function (q, fn) {
  request(googleUrl +
   'q=HedgeHog+' + q,
    {json: true},
    function(e,r,b) { fn(b); }
  );
});
              
            
            

Select

Template

              
<li ng-repeat="hog in hogs" >
  <a href="#" ng-click="select(hog)">
  <div class="media">
    <div class="chevron pull-right">
      <i class="icon-chevron-right"></i>
    </div>
    <div class="pull-left">
      <img class="media-object" 
        ng-src="{{hog.tbUrl}}" />
    </div>
    <div class="media-body">
      <h4>
        <div ng-bind-html-unsafe="hog.title">
        </div>
      </h4>
    </div>
  </div>
  </a>
</li>
              
            

Select

Client-Side

              
$scope.select = function(hog) {
  $scope.selected = hog.url;
};
              
            

Submit

Template

              
<div class="row">
  <img ng-src="{{selected}}"></img>
</div>
<div class="row">
<button 
  style="margin-top: 20px;"
  class="btn pull-right" 
  ng-show="selected"
  ng-click="submit()">Submit</button>
</div>
              
            

Submit

Client Side

              
$scope.submit = function() {
  socket.emit('submit', $scope.selected);
  $location.path('/vote');
};
            
            

Submit

Server Side

            
socket.on('submit', function(url) {
// add to database
db.put(uuid.v1(), url);
// broadcast to listeners
io.sockets.emit('addHog', url);
});

          
          

List

Client

              
socket.on('addHog', function(hog) {
  $scope.hogs.push(hog);
});
socket.emit('hogs');
              
            

List

Server

              
socket.on('hogs', function() {
  db.createReadStream().on('data', function(data) { 
    var obj = JSON.parse(data.value);
    var hog = {id: data.key, url: obj.url, votes:  obj.votes };
    socket.emit('addHog', hog);
  });
});
                
              
            

Vote

Template

              
<div class="span2" ng-repeat="hog in hogs">
  <a href="#" ng-click="vote(hog)">
    <img 
      style="height: 120px; width: 120px;"
      ng-src="{{hog.url}}" 
     />
  </a>
</div>
                
              
            

Vote

Client

              
$scope.vote = function(hog) {
  socket.emit('vote', hog);
  $location.path('/leaders');
};
              
            

Vote

Server

              
socket.on('vote', function(hog) {
  db.put(hog.id, JSON.stringify({
    url: hog.url, 
    votes: hog.votes + 1
  }));
});
              
            

Leaders

Template

              
<div class="span2" 
  ng-repeat="hog in hogs 
    | orderBy: '-votes'">
  <a href="#" ng-click="vote(hog)">
    <img 
      style="height: 120px; width: 120px;"
      ng-src="{{hog.url}}" 
     />
  </a>
  <div 
    style="padding: 30px;font-size: 3em;font-weight: bold;">
      {{hog.votes}}
  </div>
</div>                
              
            

Live Demo

More AngularJS Resources

Authentication

http-auth-interceptor

Testing

Internet Explorer

Guide

Minification

ngMin

Debugging

Batarang

Tutorial

Tutorial

Short Videos

EggHead.io

Third-party Directives and Filters

ui-bootstrap

angular-ui

ngGrid

ngModules

AngularStrap

Thank You

Questions