7

From what I understand, we use services in the case of inter and intra components communication where we hide multiple or complex data structures. Is it true we only use services in the case of persistent data structure? So what are cases we should not use services?

Vikas
  • 11,859
  • 7
  • 45
  • 69
roger
  • 1,225
  • 2
  • 17
  • 33
  • 1
    Do you have an actual programming issue? Or just a code structure question? – mast3rd3mon May 31 '18 at 13:53
  • 1
    @mast3rd3mon I am not sure which category it falls into, but it is related to understand the underlying structure and decisions we make to select one over the other. Like Array vs List. I don't know enough to tell the different, but I thought I was on the right track when I decide to go with service for data sharing between components, but is this correct? – roger May 31 '18 at 14:02
  • 2
    yes its correct using @Injectable service you can share data between components and also for call http service. – mittal bhatt May 31 '18 at 14:24
  • 1
    is this the right practice? I keep hearing about bad or good practice from what we should not use and what we can use. – roger May 31 '18 at 14:29
  • 1
    https://stackoverflow.com/a/50590418/5695162 – Vikas May 31 '18 at 14:55

2 Answers2

22

I Would beg to differ with the statement you made.

From what I understand, we use services in the case of inter and intra components communication where we hide multiple or complex data structures.

Instead of answering when we should not use angular service? I would answer what, why and when to use services?

Service

A Service is a class with a specific purpose, and In Angular, we use services mainly for three purposes.

1.To Implement any Business Logic that is independent of any Component

.
Example
Assume you want to calculate the age from DOB, Now you provide the year and The logic can give you age you would not need an HTML view to do that ,it is component Independent

2. Access to Shared Data.

When passing data between components that lack a direct connection, such as siblings, grandchildren, etc, you should use a shared service. You could either use RXJS BehaviorSubject or Subject for cross component communication.

The advantage of using BehaviorSubject or a Subject for cross-component interaction over plain getters and setters is you don't need to manually trigger a method to fetch latest data. Whenever the data is changed all the components where service is injected are automatically notified.

What is the difference between Subject and BehaviorSubject???

3. External Interactions

1.Accessing REST Web Services Using Http
-----------------------------------------------------------------------------------------------------------------------------------
Why use Services in Angular

Angular distinguishes components from services in order to increase modularity and reusability. and It's Good Practice to Delegate complex component logic to services

From Angular Style Guide
Do limit logic in a component to only that required for the view. All other logic should be delegated to services.

Do move reusable logic to services and keep components simple and focused on their intended purpose.

Why? Logic may be reused by multiple components when placed within a service and exposed via a function.

Why? Logic in a service can more easily be isolated in a unit test, while the calling logic in the component can be easily mocked.

Why? Removes dependencies and hides implementation details from the component.

Why? Keeps the component slim, trim, and focused.

Usage of Services In Angular also ensures that you are not violating DRY and SRP principles of software development.

Providing Services

FROM Angular Docs

Should you provide a service with an @Injectable decorator, in an @NgModule, or within an @Component? The choices lead to differences in the final bundle size, service scope, and service lifetime.

When you register providers in the @Injectable decorator of the service itself, optimization tools such as those used by the CLI's production builds can perform tree shaking, which removes services that aren't used by your app. Tree shaking results in smaller bundle sizes.

Angular module providers (@NgModule.providers) are registered with the application's root injector. Angular can inject the corresponding services in any class it creates. Once created, a service instance lives for the life of the app and Angular injects this one service instance in every class that needs it.

A component's providers (@Component.providers) are registered with each component instance's own injector.

Angular can only inject the corresponding services in that component instance or one of its descendant component instances. Angular cannot inject the same service instance anywhere else.

Note that a component-provided service may have a limited lifetime. Each new instance of the component gets its own instance of the service and, when the component instance is destroyed, so is that service instance

TLDR

if we want an instance of a dependency to be shared globally and share `state` across the application we configure it on the `NgModule`.

If we want a separate instance of a dependency to be shared across each instance of a component and it’s children we configure it on the components `providers` property.*


To get a Clear Picture Go through Angular's Hierarchical Dependency Injection system

Well, it's recommended to Always register application-wide services with the root AppModule which makes a service singleton(it will live as long as our application lives) but it entirely depends upon the use case.

If the sole purpose of the service is to share data between sibling components and to provide a couple of helper’s methods.Register it with component providers and make it a non-singleton service.

The benefit is that when Angular destroys the component, Angular will also destroy the service and release the memory that is occupied by it.@Credit

FAQ

Vikas
  • 11,859
  • 7
  • 45
  • 69
1

Where did you hear that is bad practice? Using service for getting data from API by HTTPRequest or sharing data between components is good practice, check my example here: Share methods between two components in same page Angular

Important thing that you have to remember is that Services are an application-wide singleton. Therfore put services only into CoreModule, and import CoreModule only once in AppModule, nowhere else. You don't want each module to have its own separate instance. (More about the difference between CoreModule and SharedModule: Angular2: CoreModule vs SharedModule)

Yet there is a real danger of that happening if the SharedModule provides the Service. It might be required for example if you are using Service for some reusable component, eg. in directive which is actually in SharedModule. Then you have to use forRoot() whilst you importing ShareModule, example:

import { NgModule, ModuleWithProviders } from '@angular/core';
import { MyDirective } from './my.directive';
import { SomeService } from './some.service';

@NgModule({
  declarations: [
    MyDirective
  ],
  exports: [
    MyDirective
  ]
})
export class SharedModule {
  static forRoot(): ModuleWithProviders {
    return {
      ngModule: SharedModule,
      providers: [ SomeService ]
    };
  }
}

Some other module:

import { SharedModule } from './shared/shared.module';

@NgModule({
  imports: [
    SharedModule.forRoot()
  ]
})
export class SomeModule {}

I hope it helps :)

DiPix
  • 5,755
  • 15
  • 61
  • 108
  • No Angular Services do NOT have to be always Singletons it Depends on the use case. One of the disadvantages is You are not releasing memory when you register it with `ngModule's` providers array. – Vikas May 31 '18 at 15:07
  • The info in this answer is WAY wrong. Mad to see how mixed up people get with dependency injection - there must be some crazy apps being written out there:-) – Drenai May 31 '18 at 15:40
  • I discuss my plan with someone, and he suggested i shouldn’t use service because it should only be used with data that needs to sit there for a while. While what I need to do is only displaying data from the data. My argument is I have complex manipulation and multiple components, therefore it should be right to use it. – roger May 31 '18 at 15:50
  • @vikas I see that since it declare in the up in the root and hold on to memory maybe that why I should only use when it is necessary – roger May 31 '18 at 15:52