0

I'm implementing websockets with angularjs factory.

angular.
module('core.socket').
factory('Socket', ['$rootScope', function($rootScope){
    var ws;
    var stack = [];
    var onmessageDefer;
    function socket(url){
      ws = new WebSocket(url);
      ws.onopen = function(event) {
          for (i in stack) {
              ws.send(stack[i]);
          }
          stack = [];
          if (onmessageDefer) {
              ws.onmessage = onmessageDefer;
              onmessageDefer = null;
          }
      };
    }

    socket.prototype = {
      send: function(data) {
          data = JSON.stringify(data);
          if (ws.readyState == 1) {
              ws.send(data);
          } else {
              stack.push(data);
          }
      },
      onmessage: function(callback) {
          if (ws.readyState == 1) {
              ws.onmessage = callback;
          } else {
              onmessageDefer = callback;
          }
      }
    }

    return socket;
}]);

And Socket factory is passed to a controller as:

angular.
module('common').
controller('noteVBoxController', ['$scope', '$location','$element', 'Socket',
 function($scope, $location, $element, Socket){
  var self = this;
  self.socket = new Socket("ws://192.168.225.59:8010/ws/");
  $scope.submit = function(){
    self.socket.send({
      type: "place_note",
      data: {
        noteId: $scope.note.id
      }
    });
  };
  self.socket.onmessage(function(event) {
      var data = JSON.parse(event.data);
      $scope.note.top_note=data["message"];
  });

}]);

As you can see the callback function is passed to factory, where the current $scope is not available to the function. Please help.

The main problem is, If I use this controller with multiple directive elements, the last elements scope is only available inside the onmessage function.

georgeawg
  • 48,608
  • 13
  • 72
  • 95
Sreekanth Reddy Balne
  • 3,264
  • 1
  • 18
  • 44
  • Passing a function with `$scope` to a factory will create a [closure](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures). To avoid memory leaks, the factory needs to remove any reference to the function when scope is destroyed. Use the [$destroy event](https://docs.angularjs.org/api/ng/type/$rootScope.Scope#event-$destroy) to implement clean-up. – georgeawg Dec 01 '18 at 18:52
  • To have multiple subscribers to an event handler, I recommend using [rxJS](https://stackoverflow.com/tags/rxjs/info). Subscription instances include an `.unsubscribe` method for proper clean-up. – georgeawg Dec 01 '18 at 19:09

0 Answers0