Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular 8: Define a utils service as singleton and with static methods?

I'm currently starting with Angular 8. Now I want to write a service containing util functions ("CoreService"). But I'm wondering how exactly I should do that and what are the advantages or disadvantages of the different options:

  1. Should I define it as a singleton?
  2. Should I define the functions as static methods (called by CoreService.doSomething()) or should I define it as an injectable class with non-static methods (injected in constructor)?

Maybe one of the options has more or less impact on performance (memory?).

Any answer is highly appreciated!

Bye The_Unknown

like image 894
The_Unknown Avatar asked Feb 02 '26 02:02

The_Unknown


1 Answers

Okay, lets tackle down Services in Angular. Let's get straight on some details first.

The recommended way to create services is by using the CLI:

ng generate service foo/weather

This will create a new service under src/app/foo/weather.service.ts - along with some skeleton for your tests. If you inspect this code, you'd see that it looks something like this:

@Injectable({
  providedIn: 'root',
})
export class WeatherService {
  constructor() { }
}

1. Singleton or not

Now look above at the providedIn: 'root' line. This way you are basically saying that Angular should provide this service at the root level. In this case Angular will create a single, shared instance of your WeatherService and will inject this single instance into any component wanting it. In addition, from the Angular documentation:

Registering the provider in the @Injectable() metadata also allows Angular to optimize an app by removing the service from the compiled app if it isn't used.

So this might also save you a bit of bandwidth.

Of course services are there to be used by other components. If you decide to register a provider at the component level, you'll get a new instance of your service with each new instance of that component. It will be something like this:

@Component({
  selector:    'app-cities',
  templateUrl: './cities.component.html',
  providers:  [ WeatherService ]
})

There is also a third "level" of granularity - scoped to a module - if you want to have an instance of your service available to all the components but just in the said module:

@NgModule({
  providers: [
    WeatherService,
    AnotherService
  ],
  ...
})

In a nutshell - you are in control of how you want to have your service - as a singleton or not - with all the implications.

2. Static or instance methods

In my opinion this is not really a question. The way to go is using instance methods. This is anyway a bit enforced through the dependency injection of Angular. The components you will create will ask for an instance of your service. Angular's DI will provide one (singleton or a new one) and you can work with this one as with any other instantiated object:

@Injectable({
  providedIn: 'root',
})
export class WeatherService {
  getTodaysTemperature() { return 7; }
}

@Component({
   ... // omitted for simplicity
})
export class TemperatureComponent {
  constructor(weatherService: WeatherService) {
      this.temperature = weatherService.getTodaysTemperature();
  }
}

So just make sure that you provide the corresponding instance methods and you are good to go. Testing would also be fine as you can inject your service or even mock it.

like image 131
Anton Avatar answered Feb 04 '26 16:02

Anton