1

Imagine the following situation. Component A updates an array A in Service A. Component B uses/reads array A in Service A. If I want to Component B to be notified...when component A updates the Array, I could use a singleton, but my feeling...(coming from a C# + MVVM background) a singleton service would be overkill as this is only used by those 2 components in the application.

Is there an alternative, or should I just go ahead and create a singleton service?

Any advice is appreciated,

Thank you,

Maniac_1979
  • 879
  • 3
  • 10
  • 26

3 Answers3

2

No, it's not overkill at all, and would seem a perfectly idiomatic solution.

Angular2 services are (often) singletons.

It's my understanding that if you:

  • Decorate your Service with @Injectable
  • Add your Service to providers[] in @NgModule,
  • import your service into your Components

you should share the same, single instance of that Service.

You can, if you choose, declare the Service as a provider to a component by including it in the @Component decorator's provider[] list, which will instantiate a new instance of the Service for the component. This is useful if you wish to provide functionality without sharing state.

Here is an informative and jovial write-up on this behaviour: https://blog.budacode.com/2016/06/02/angular-2-services/

msanford
  • 11,803
  • 11
  • 66
  • 93
  • Its not always true that services are singleton only. It depends how you declare them. – micronyks Oct 24 '16 at 18:19
  • FYI...the way you declare service demonstrates older way of declaring service (probably in beta version of Angular2) – micronyks Oct 24 '16 at 18:22
  • Could you elaborate on the "he way you declare service demonstrates older way of declaring service"? What is the new way? – Maniac_1979 Oct 24 '16 at 18:24
  • I guess Maniac refers to the fact that with 2.x.x versions you can (and most often you should) define providers at Angular2 Module level. Official documentation gives a lot of details. – Picci Oct 24 '16 at 18:35
  • @micronyks This is true; it's also true that singletons can be re-instantiated (in my experience, often by accident) through things like navigation. Also, this is the pre-2-stable way of declaring a service, but I was merely quoting from the original thread. I'll edit to clarify. – msanford Oct 24 '16 at 18:35
  • 1
    I guess what @micronyks means is, where you **provide** a service defines the scope of the service. Angular2 DI maintains a single instance (singleton) per provider. If you want two components to share a service instance and the components are parent and child you can provide the service at the parent and only the parent and it's children can inject this service (limiting the scope). If the components that are supposed to communicate are not parent-child then you can choose some other common parent to provide the service at. – Günter Zöchbauer Oct 25 '16 at 05:07
  • 1
    If you provide a service at a component a provider is created for each component instance. To have an application-wide singleton provide the service in `@NgModule()`. Even if multiple modules provide the same service, only one provider is actually created for the whole application. Lazy loaded modules have their own root scope. – Günter Zöchbauer Oct 25 '16 at 05:08
  • 1
    @GünterZöchbauer describes exactly what I wanted to convey. – micronyks Oct 25 '16 at 05:20
  • Thank you all for the clarifications! – msanford Oct 25 '16 at 15:00
2

If an array is updated in ServiceA by ComponentA and omponentB uses/reads that updated array from serviceA only, you must use singleton service only so that ComponentA and ComponentB will use/share single instance of ServiceA.

So any update made by componentA to SeviceA will also be available in ComponentB because of single instance.

micronyks
  • 54,797
  • 15
  • 112
  • 146
1

Going with a Service would be the "standard" Angular approach to this, and as msanford pointed out, that´s completely fine. Since ng2 is quite flexible, you also could take other ways like using a redux implementation (like https://github.com/ngrx/store).

Stefan Negele
  • 1,092
  • 10
  • 10