Question

I'm learning angular, experimenting with different ways of using services/factories, and am trying to wrap my head around the unique sense in which they are "singletons".

I have an API service that exposes domain models and wraps functionality for retrieving them from my REST server. This service can be easily comprehended as a singleton in the classic sense: I want a single instance to be shared across my application, with a state that can be observed by many different controllers, enabling those controllers to "synchronize" with each other through the conduit of the service: The controllers stay in sync not by being aware of (and thus coupled with) each other directly, but by being aware of this common service. (side question: is this a correct characterization of the role of a service?)

This is a use-case where a singleton service is clearly and unambiguously appropriate. But:

One of the domain objects that gets returned by the API service is called thread, which is essentially a wrapper around a linked-list of points. In addition to the list of points, a thread has a currentPoint variable and a next() function, which pops the next value from the list and makes it the currentPoint.

My UI visualizes a thread simultaneously in two different ways - in two separate elements with their own controllers and directives. Each of these elements contains a button that, when clicked, calls nextPoint() and thereby changes the state of the thread. When this button is pushed in one element, the state of the thread needs to be updated in both elements - so, here again we have a situation where a service seems ideal.

But, at any given time, there can be an arbitrary number of threads being displayed, each of which should be independent and unaware of each other - which conflicts with (what I understand to be) the "classic" sense of "singleton".

Is there a word for this sort of thing in angular?

I've experimented/looked into this enough to know that it's certainly possible to create these "non-singleton singletons" using factorys, but surely there must be a better term for them than "non-singleton singletons" - I cringed both times I just typed it.

Second, what is the best way of implementing one? Can the strategy illustrated below (which I found in an angular github issue here) be regarded as a best practice?

myApp.factory('myServiceProvider',function(){
    var serviceProvider=function(){};
    serviceProvider.prototype.foo=function(){};

    var service = {
        getInstance:function(){ return new serviceProvider(); }
    }

    return service;
});

//Singleton Services
myApp.factory('myService',['myServiceProvider',function(myServiceProvider){
    return myServiceProvider.getInstance();
}]);

//Where non-singletons are required
function myController(myServiceProvider){
    var instance_a=myServiceProvider.getInstance();
    var instance_b=myServiceProvider.getInstance();
};

//Where singleton service is required
function myOtherController(myService){
    myService.foo();
};
Was it helpful?

Solution

An angular singleton is not exactly the classic. A singleton in angular is basically one instance of an object that holds a single state. That state can be data bindable via a services allowing for value sharing. This means that you can have a service property that is bound across all of its uses an app; one change will be reflected everywhere. The singleton persists through the life of the app. If the app is refreshed the singleton will loose value until it is set again by the app via a user interaction or a storage retrieval.

I like the pattern you are using. I also tend to use it. Here is an example of a web storage service I recently made similar to your service, https://github.com/breck421/WebStorage/blob/master/src/js/WebStorage.js.

I hope this helps and feel free to continue this dialog :)

Thanks,

Jordan

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top