elghazal-a
elghazal-a

Reputation: 590

Angular.js: How can I avoid caching services?

I have a service that's connecting my clients to the Socket.io server :

var serviceSocketIo = angular.module('myApp.services', []);

serviceSocketIo.factory('mySocket',['$rootScope', '$routeParams', function ($rootScope, $routeParams) {
  var base = $rootScope.base, //base = 'http://localhost:3000'
  channel = '/' + $routeParams.game,
  url = base + channel,
  mySocket;

  console.log('service: connection to ' + url);
  mySocket = io.connect(url);
  return {
    base: base,
    channel: channel,
    socket: mySocket,
    on: function (eventName, callback) {
      mySocket.on(eventName, function () {  
        var args = arguments;
        $rootScope.$apply(function () {
          callback.apply(mySocket, args);
        });
      });
    },
    emit: function (eventName, data, callback) {
      mySocket.emit(eventName, data, function () {
        var args = arguments;
        $rootScope.$apply(function () {
          if (callback) {
            callback.apply(mySocket, args);
          }
        });
      })
    }
  };
}]);

Please note that the namespace depends on the $routePrams paramaters.

What I need is to delete the service from cache before instanciate it. So I'll be sure the services will connect clients to the right url. Or if there is an other way to force my service to check the parameters ?

Upvotes: 1

Views: 347

Answers (3)

Bart
Bart

Reputation: 17361

What's letting you from creating a service that creates the socket for you?

var services = angular.module('myApp.services', []);

services.service('SocketService', function () {
    var SocketService = function () {
        this.createSocket = function (url) {
            return io.connect(url);
        }
    };

    return SocketService;
});

Upvotes: 1

basarat
basarat

Reputation: 276161

Factories and Services in angular are singletons and there is no configuration to make them otherwise. If you want such control you need to use methods on the $provide object:

Get access to provide using app.config:

app.config(function($provide) {
   // Now you have provide 
});

You can use it to create your own custom instantiation policy using what you return from $get:

$provide.provider('foo', function(){
  this.$get = function(dep) {...}
});

Reference: http://slides.wesalvaro.com/20121113/#/2/6

Upvotes: 1

basarat
basarat

Reputation: 276161

The services / factory methods are run only once and from that point on the return value is used. If you want to customize the capabilities of what you return, put these as arguments in the function members of what you return. e.g. notice yourArg:

var serviceSocketIo = angular.module('myApp.services', []);

serviceSocketIo.factory('mySocket',['$rootScope', '$routeParams', function ($rootScope, $routeParams) {
  var base = $rootScope.base, //base = 'http://localhost:3000'
  channel = '/' + $routeParams.game,
  url = base + channel,
  mySocket;

  console.log('service: connection to ' + url);
  mySocket = io.connect(url);
  return {
    base: base,
    channel: channel,
    socket: mySocket,
    // Notice yourArg 
    on: function (eventName, callback, yourArg) {
      // Use yourArg to customize behaviour: 
      mySocket.on(eventName, function () {  
        var args = arguments;
        $rootScope.$apply(function () {
          callback.apply(mySocket, args);
        });
      });
    },
    emit: function (eventName, data, callback) {
      mySocket.emit(eventName, data, function () {
        var args = arguments;
        $rootScope.$apply(function () {
          if (callback) {
            callback.apply(mySocket, args);
          }
        });
      })
    }
  };
}]);

Upvotes: 0

Related Questions