Q: AngularJs - RequireJs - Socket.io : Not playing well together I have a 2 part issue:
I. --- When I load socket.io in my requirejs path file, while it may appear in browser's scripts collection, the moment I use it in a factory object, I receive the error, "io" is not defined. I do not get the error however, if I load socket.io.js from the HTML page directly. I found another person had the exact issue here but with no resolution.
II. --- I am using ocLazyLoad, and my app is modularized per function. I opted to place the $socket factory object I copied from Brian Ford's example directly in my root module ['app']. I know services in a lazyload scenario need to be loaded every time they are used, regardless of prior calls to them. But, this seems wrong. If I wish to make my app real time, that means I have to list it as a dependency in every state. There should be a more efficient way to do this but I cannot see how.
Issue I:


*

*Establishing RequireJs dependency and adding to bootstrap
a. RequireJs's path file:
  //socket.io
  'socket.io' : '/vendor/socket.io-client/lib/socket.io'
  //shim
  'socketio': {exports: 'io'}

b. Bootstrap file
window.name = "NG_DEFER_BOOTSTRAP!";
  define([
    'require',
    'jquery',
    'socket.io',
    'angular',
     .....

Observation: This is all working as expected, as evidenced by socket.io.js now in my browser's scripts collection on page load.

*$socket factory service
a. app.socket.js (factory file from Brian Ford) file:  

   define(['app'], function (app) {
   app.factory('$socket',['$rootScope', function ($rootScope) {
     /////////////////////
     // PROBLEM IS HERE //
     /////////////////////
      var socket = io.connect();
      return {
        on: function (eventName, callback) {
            socket.on(eventName, function () {
                var args = arguments;
                $rootScope.$apply(function () {
                    callback.apply(socket, args);
                });
            });
        },
        emit: function (eventName, data, callback) {
            socket.emit(eventName, data, function () {
                var args = arguments;
                $rootScope.$apply(function () {
                    if (callback) {
                        callback.apply(socket, args);
                    }
                });
            })
        }
    };
}]); });


b. Controller using $socket factory

 define(['angular'], function(ng) {
  'use strict';

  /* @ngInject */
  MyDashboardCtrl.$inject = ['$socket','MyDashboardSvc'];
  ng.module('MyDashboard').controller('MyDashboardCtrl', MyDashboardCtrl);
  function MyDashboardCtrl($socket, MyDashboardSvc) {
  ....


Obervation: With socket.io.js being loaded from require's path file, once the controller calls the factory as a dependency, I receive this error:
              ReferenceError: io is not defined

If instead, I load socket.io.js straight from the HTML, the problem goes away:

<script src="vendor/socket.io-client/lib/socket.io.js"></script> 
<script src="app/require/rconfig.js"></script> 
<script src="vendor/requirejs/require.js" data-main="app/app.bootstrap.js"></script>


Issue II:
I would like to make my entire app real time. Does that mean, if I intend to utilize lazy loading, I will need to list the $socket factory in every BLESSED $state? 

A: I hate my solution.  I put the socket.io object on the windows inside of requirejs, and then find it there using the $window object in angular. It really is atrocious - but it will allow me to continue to code while I find a better solution.  Here lie the relevant and irrelevant bits: 
<script text="text/javascript">
    require.config({
      paths: {
        angular: "<path to angular>" 
        socketIO: [
            "/socket.io/socket.io"
        ],
        myNgApplicationJs: "/client/my-angular-all"
      },
      shim: {
        socketIO: { deps: [] },
        angular: { deps: [
            "jQuery",
            "socketIO"
        ] },
        myNgApplicationJs: {deps: [
            "angular", "socketIO"
        ]}
      }
    });

    require([
        "myNgApplicationJs"
        ,"socketIO"
    ], function(noop, io) {

        // a hack to make the socket.io available on the $window in angular
        window.io = io

        angular.bootstrap(document, ['myNgApplication']);

        return {};
    });
</script>

Then (based off of code poached from Brian Ford):
angular.module('myNgApplication').factory('MySocketIO', function ($log, $window, $rootScope) {

    if(!$window.io) {
        throw new Exception("assure the socket.io is added to the window object. e,g, window.io")
    }

    // Hack socket.io off of the $window object 
    var io = $window.io
    var socket = io();

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

This allows me to abstract away the hack - the best I can.  Should I find a better solution I only need to change requirejs peice and the MySocketIO implementation. 
I then code up business level factories like this:
angular.module('myNgApplication').factory('BlahProxy', function ($log, MyHttp, MySocketIO) {
    var Blah = {}

    Blah.onUpdate = function(callback) {
        // don't expose socket-io message type to the controllers
        MySocketIO.on('send:testIV', callback)
    }

    return Blah
})

Then leverage those factories in my controllers:
angular.module('myNgApplication').controller('myBlahGridCtrl', function ($scope, $log, BlahProxy) {

    $scope.messages = []

    // handle whatever message types explicitly
    BlahProxy.onUpdate(function (message) {
        $scope.messages.push(message);
    })

})


A: I was facing the same problem, It solved by adding 'socket.io' in my socketfactory file dependencies. In your case, try the following change:
a. app.socket.js file:
   define(['app', 'socket.io'], function (app, io) {
      app.factory('$socket',['$rootScope', function ($rootScope) {
          //........

