Mastering Angular Services: Essential Concepts for Beginners
Tags: angular, typescript, frontend, webdev
Published: 2023-05-13 17:43:17

Angular services play a crucial role in developing robust and modular web applications. As a developer, understanding the basics of services in Angular is essential for building maintainable and scalable code. This blog will cover the fundamental concepts of services in Angular, including how to create and use services, share data between components, and make API requests using built-in services.

Whether you're just starting with Angular or looking to improve your existing skills, this guide will provide a solid foundation for working with services in your Angular applications.

## Prerequisites

Before diving into this guide on Angular services, it is recommended that readers have a basic understanding of Angular concepts, including components, modules, and dependency injection. Familiarity with TypeScript and web development fundamentals such as HTML, CSS, and JavaScript is also helpful.

This guide is intended for beginners who are just getting started with Angular services, but a foundation in these topics will aid in understanding the material covered.

Let's get started and learn something exciting today!

## What are services in Angular?

In Angular, a **service** is a class used to encapsulate shared data and functionality that can be used across multiple components. Services act as a central place to store data and business logic, making it easy to share data and functionality between components without repeating code or passing data through many levels of the component hierarchy.

Services are typically used to implement data access methods, handle API requests, or perform any other business logic that needs to be shared across components. Services are usually created using the @Injectable decorator, which marks the class as a service that can be injected into other components.

Here's an example of a simple service that has a single property and method:

```typescript
import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'root'
})
export class TestService {
  private data: string[] = ['apple', 'banana', 'cherry'];

  getData(): string[] {
    return this.data;
  }
}
```

In this example, the `TestService` class is marked as a service using the `@Injectable` decorator. The `providedIn` property is set to `'root'`, which means that the service is available globally throughout the application.

The `TestService` class has a private property called **data**, which is an array of strings. The class also has a public method called `getData`, which returns the **data** property.

Using this service, we can easily share the **data** property and `getData` method between multiple components in our application.

## Creating a basic service

Creating a basic service in Angular is a straightforward process. The first step is to create a new class that will act as the service. Once the class has been created, we can use the `@Injectable` decorator to indicate that the class is a service that can be injected into other components. Finally, we need to provide the service to our application using the `providers` array.

Here's an example of creating a simple service that generates random numbers:

```typescript

import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'root'
})
export class NumberService {
  getRandomNumber(): number {
    return Math.floor(Math.random() * 100);
  }
}
```
In this example, we have created a new class called `NumberService`. We have also added the `@Injectable` decorator to indicate that this class is a service.

The `NumberService` class has a single method called `getRandomNumber` that returns a random number between 0 and 100.

_Bonus: It is a good practice to have the word service in the name of the file. For example above service can be names as `number-service.service.ts`._

Now that we have created our service, we need to provide it to our application using the `providers` array. We can do this in the `@NgModule` decorator of our **AppModule**:

```typescript
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';

import { AppComponent } from './app.component';
import { NumberService } from './number.service';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule
  ],
  providers: [NumberService],
  bootstrap: [AppComponent]
})
export class AppModule { }
```

In this example, we have imported our `NumberService` class and added it to the `providers` array in our `@NgModule` decorator. Now, the `NumberService` can be injected into any component that needs it.

## Injecting a service into a Component

Now that we have created a service, we need to be able to use it in our Angular components. This is done by injecting the service into the component's constructor.

Here's an example of how to inject a service into a component.

```typescript
import { Component } from '@angular/core';
import { NumberService } from './number.service';

@Component({
  selector: 'app-random-number',
  template: `
    <p>Random Number: {{ randomNumber }}</p>
  `
})
export class RandomNumberComponent {
  randomNumber: number;

  constructor(private numberService: NumberService) {
    this.randomNumber = this.numberService.getRandomNumber();
  }
}
```

In this example, we have created a new component called `RandomNumberComponent`. We have also imported our `NumberService` and added it to our component's constructor.

The `NumberService` is now available in our component as `numberService`. We can call any method on the service from within our component, just like we would with any other object.

In our component's constructor, we are using the `numberService` to generate a random number. We then store that number in the `randomNumber` property of our component.

Now, whenever our `RandomNumberComponent` is created, it will generate a new random number using the `NumberService`. This number can then be displayed in the component's template.

**Injecting services into components is a powerful feature of Angular, as it allows us to share data and functionality between components without repeating code.**

The `NumberService` can also be used in any other component similarly, thus preventing any repeated code where the methods of `numberService` is required.

## Using the HttpClient service for API requests

The `HttpClient` service is a powerful tool in Angular for making API requests and retrieving data from external sources. This section will explore how to use the `HttpClient` service to make HTTP requests and handle the response.

First, we need to import the `HttpClientModule` in our `app.module.ts` file to make it available throughout our application:

```typescript
import { HttpClientModule } from '@angular/common/http';

@NgModule({
  imports: [
    HttpClientModule
  ],
  ...
})
```

Next, create a service that will use the `HttpClient` to request an API. For example, let's say we want to retrieve a list of users from the JSONPlaceholder API:

```typescript
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';

@Injectable({
  providedIn: 'root'
})
export class UserService {
  private apiUrl = 'https://jsonplaceholder.typicode.com/users';

  constructor(private http: HttpClient) {}

  getUsers() {
    return this.http.get(this.apiUrl);
  }
}
```

In this example, we create a new service called `UserService` and define a private property called `apiUrl` that holds the URL of the API endpoint we want to access. Inject the `HttpClient` service into the constructor of our service, and define a method called `getUsers()` that makes an HTTP GET request to the API using the `http.get()` method.

Now, use the `UserService` to retrieve the list of users in a component:

```typescript
import { Component } from '@angular/core';
import { UserService } from './user.service';

@Component({
  selector: 'app-user-list',
  template: `
    <ul>
      <li *ngFor="let user of users">{{ user.name }}</li>
    </ul>
  `
})
export class UserListComponent {
  users: any[];

  constructor(private userService: UserService) {}

  ngOnInit() {
    this.userService.getUsers().subscribe((data: any[]) => {
      this.users = data;
    });
  }
}
```

In this example, we inject the `UserService` into our `UserListComponent` and use the `getUsers()` method to retrieve the list of users from the API. We use the `subscribe()` method to handle the response from the API and store the list of users in a property called `users`. We can then use *ngFor to iterate over the users array and display each user's name in our template.

Using the `HttpClient` service, we can easily make API requests and retrieve data from external sources in our Angular applications. This can make building dynamic, data-driven applications that can access and display information from various sources easier.

## Conclusion
In conclusion, services are crucial to building robust and efficient Angular applications. By understanding the basics of services in Angular and how to create and use them, we can build more scalable and maintainable applications.

Lastly, Your support keeps me going, and I give my 100 percent to these blogs! If you've found value, consider fueling the blog with a coffee ☕️ donation at the below link. 

[**Buy me a COFFEE!**](https://www.buymeacoffee.com/ayushdev)

Thank you! 🙏