# 4. Add services

The Tour of Heroes `HeroesComponent` is getting and displaying fake data.

Refactoring the `HeroesComponent` focuses on supporting the view and making it easier to unit-test with a mock service.

## Why services <a href="#why-services" id="why-services"></a>

Components shouldn't fetch or save data directly, and they certainly shouldn't knowingly present fake data. They should focus on presenting data and delegate data access to a service.

This tutorial creates a `HeroService` that all application classes can use to get heroes. Instead of creating that service with the [`new`keyword](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Operators/new), use the [*dependency injection*](https://v16.angular.io/guide/dependency-injection) that Angular supports to inject it into the `HeroesComponent` constructor.

Services are a great way to share information among classes that *don't know each other*. Create a `HeroService` next and inject it in the `HeroesComponent`, to provide hero data.

## Create the `HeroService` <a href="#create-the-heroservice" id="create-the-heroservice"></a>

Run `ng generate` to create a service called `hero`.

```bash
ng generate service hero
```

The command generates a skeleton `HeroService` class in `src/app/hero.service.ts` as follows:

{% tabs %}
{% tab title="src/app/hero.service.ts (new service)" %}

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

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

  constructor() { }

}
```

{% endtab %}
{% endtabs %}

### `@`[`Injectable`](https://v16.angular.io/api/core/Injectable)`()` services <a href="#injectable-services" id="injectable-services"></a>

Notice that the new service imports the Angular [`Injectable`](https://v16.angular.io/api/core/Injectable) symbol and annotates the class with the `@`[`Injectable`](https://v16.angular.io/api/core/Injectable)`()` decorator. This marks the class as one that participates in the *dependency injection system*. The `HeroService` class is going to provide an injectable service, and it can also have its own injected dependencies. It doesn't have any dependencies yet.

The `@`[`Injectable`](https://v16.angular.io/api/core/Injectable)`()` decorator accepts a metadata object for the service, the same way the `@`[`Component`](https://v16.angular.io/api/core/Component)`()` decorator did for your component classes.

### Get hero data

The `HeroService` could get hero data from anywhere such as a web service, local storage, or a mock data source.

Removing data access from components means you can change your mind about the implementation anytime, without touching any components. They don't know how the service works.

The implementation in *this* tutorial continues to deliver *mock heroes*.

Import the `Hero` and `HEROES`.

{% tabs %}
{% tab title="src/app/hero.service.ts" %}

```typescript
import { Hero } from './hero';
import { HEROES } from './mock-heroes';
```

{% endtab %}
{% endtabs %}

Add a `getHeroes` method to return the *mock heroes*.

{% tabs %}
{% tab title="src/app/hero.service.ts" %}

```typescript
getHeroes(): Hero[] {
  return HEROES;
}
```

{% endtab %}
{% endtabs %}

## Provide the `HeroService` <a href="#provide-the-heroservice" id="provide-the-heroservice"></a>

You must make the `HeroService` available to the dependency injection system before Angular can *inject* it into the `HeroesComponent` by registering a *provider*. A provider is something that can create or deliver a service. In this case, it instantiates the `HeroService` class to provide the service.

To make sure that the `HeroService` can provide this service, register it with the *injector*. The *injector* is the object that chooses and injects the provider where the application requires it.

By default, `ng generate service` registers a provider with the *root injector* for your service by including provider metadata, that's `providedIn: 'root'` in the `@`[`Injectable`](https://v16.angular.io/api/core/Injectable)`()` decorator.

```typescript
@Injectable({
  providedIn: 'root',
})
```

When you provide the service at the root level, Angular creates a single, shared instance of `HeroService` and injects into any class that asks for it. Registering the provider in the `@`[`Injectable`](https://v16.angular.io/api/core/Injectable) metadata also allows Angular to optimize an application by removing the service if it isn't used.

{% hint style="info" %}
To learn more about providers, see the [Providers section](https://v16.angular.io/guide/providers). To learn more about injectors, see the [Dependency Injection guide](https://v16.angular.io/guide/dependency-injection).
{% endhint %}

The `HeroService` is now ready to plug into the `HeroesComponent`.

{% hint style="warning" %}
This is an interim code sample that allows you to provide and use the `HeroService`. At this point, the code differs from the `HeroService` in the [final code review](https://v16.angular.io/tutorial/tour-of-heroes/toh-pt4#final-code-review).
{% endhint %}

## Update `HeroesComponent` <a href="#update-heroescomponent" id="update-heroescomponent"></a>

Open the `HeroesComponent` class file.

Delete the `HEROES` import, because you won't need that anymore. Import the `HeroService` instead.

{% tabs %}
{% tab title="src/app/heroes/heroes.component.ts (import HeroService)" %}

```typescript
import { HeroService } from '../hero.service';
```

{% endtab %}
{% endtabs %}

Replace the definition of the `heroes` property with a declaration.

{% tabs %}
{% tab title="src/app/heroes/heroes.component.ts" %}

```typescript
heroes: Hero[] = [];
```

{% endtab %}
{% endtabs %}

### Inject the `HeroService` <a href="#inject-the-heroservice" id="inject-the-heroservice"></a>

Add a private `heroService` property of type `HeroService` to the component.

{% tabs %}
{% tab title="src/app/heroes/heroes.component.ts" %}

<pre class="language-typescript"><code class="lang-typescript"><strong>private heroService = inject(HeroService);
</strong></code></pre>

{% endtab %}
{% endtabs %}

The parameter simultaneously defines a private `heroService` property and identifies it as a `HeroService` injection site.

When Angular creates a `HeroesComponent`, the [Dependency Injection](https://v16.angular.io/guide/dependency-injection) system sets the `heroService` property to the singleton instance of `HeroService`.

### Add `getHeroes()` <a href="#add-getheroes" id="add-getheroes"></a>

Create a method to retrieve the heroes from the service.

{% tabs %}
{% tab title="src/app/heroes/heroes.component.ts" %}

```typescript
getHeroes(): void {
  this.heroes = this.heroService.getHeroes();
}
```

{% endtab %}
{% endtabs %}

### Call it in `ngOnInit()` <a href="#call-it-in-ngoninit" id="call-it-in-ngoninit"></a>

While you could call `getHeroes()` in the constructor, that's not the best practice.

Reserve the constructor for minimal initialization such as wiring constructor parameters to properties. The constructor shouldn't *do anything*. It certainly shouldn't call a function that makes HTTP requests to a remote server as a *real* data service would.

Instead, call `getHeroes()` inside the [*ngOnInit lifecycle hook*](https://v16.angular.io/guide/lifecycle-hooks) and let Angular call `ngOnInit()` at an appropriate time *after* constructing a `HeroesComponent` instance.

{% tabs %}
{% tab title="src/app/heroes/heroes.component.ts" %}

```typescript
ngOnInit(): void {
  this.getHeroes();
}
```

{% endtab %}
{% endtabs %}

Important! The class should implement the matching Interface:

```typescript
export class HeroesComponent implements OnInit {...}
```

### See it run <a href="#see-it-run" id="see-it-run"></a>

After the browser refreshes, the application should run as before, showing a list of heroes and a hero detail view when you click a hero name.

## Observable data <a href="#observable-data" id="observable-data"></a>

The `HeroService.getHeroes()` method has a *synchronous signature*, which implies that the `HeroService` can fetch heroes synchronously. The `HeroesComponent` consumes the `getHeroes()` result as if heroes could be fetched synchronously.

{% tabs %}
{% tab title="src/app/heroes/heroes.component.ts" %}

```typescript
this.heroes = this.heroService.getHeroes();
```

{% endtab %}
{% endtabs %}

This approach won't work in a real application that uses asynchronous calls. It works now because your service synchronously returns *mock heroes*.

If `getHeroes()` can't return immediately with hero data, it shouldn't be synchronous, because that would block the browser as it waits to return data.

`HeroService.getHeroes()` must have an *asynchronous signature* of some kind.

In this tutorial, `HeroService.getHeroes()` returns an `Observable` so that it can use the Angular `HttpClient.get` method to fetch the heroes and have `HttpClient.get()` return an `Observable`.

### Observable `HeroService`

`Observable` is one of the key classes in the [RxJS library](https://rxjs.dev/).

In the tutorial on HTTP, you can see how Angular's `HttpClient` methods return RxJS `Observable` objects. This tutorial simulates getting data from the server with the RxJS `of()` function.

Open the `HeroService` file and import the `Observable` and `of` symbols from RxJS.

{% tabs %}
{% tab title="src/app/hero.service.ts (Observable imports)" %}

```typescript
import { Observable, of } from 'rxjs';
```

{% endtab %}
{% endtabs %}

Replace the `getHeroes()` method with the following:

{% tabs %}
{% tab title="src/app/hero.service.ts" %}

```typescript
getHeroes(): Observable<Hero[]> {
  const heroes = of(HEROES);
  return heroes;
}
```

{% endtab %}
{% endtabs %}

`of(HEROES)` returns an `Observable<Hero[]>` that emits *a single value*, the array of mock heroes.

{% hint style="info" %}
The [HTTP tutorial](https://v16.angular.io/tutorial/tour-of-heroes/toh-pt6) shows you how to call `HttpClient.get<Hero[]>()`, which also returns an `Observable<Hero[]>` that emits *a single value*, an array of heroes from the body of the HTTP response.
{% endhint %}

### Subscribe in `HeroesComponent` <a href="#subscribe-in-heroescomponent" id="subscribe-in-heroescomponent"></a>

The `HeroService.getHeroes` method used to return a `Hero[]`. Now it returns an `Observable<Hero[]>`.

You need to adjust your application to work with that change to `HeroesComponent`.

Find the `getHeroes` method and replace it with the following code. the new code is shown side-by-side with the current version for comparison.

{% tabs %}
{% tab title="heroes.component.ts (Observable)" %}

```typescript
getHeroes(): void {
  this.heroService.getHeroes()
      .subscribe(heroes => this.heroes = heroes);
}
```

{% endtab %}

{% tab title="heroes.component.ts (Original)" %}

```typescript
getHeroes(): void {
  this.heroes = this.heroService.getHeroes();
}
```

{% endtab %}
{% endtabs %}

`Observable.subscribe()` is the critical difference.

The previous version assigns an array of heroes to the component's `heroes` property. The assignment occurs *synchronously*, as if the server could return heroes instantly or the browser could freeze the UI while it waited for the server's response.

That *won't work* when the `HeroService` is actually making requests of a remote server.

The new version waits for the `Observable` to emit the array of heroes, which could happen now or several minutes from now. The `subscribe()` method passes the emitted array to the callback, which sets the component's `heroes` property.

This asynchronous approach *works* when the `HeroService` requests heroes from the server.

## Show messages

This section guides you through the following:

* Adding a `MessagesComponent` that displays application messages at the bottom of the screen
* Creating an injectable, application-wide `MessageService` for sending messages to be displayed
* Injecting `MessageService` into the `HeroService`
* Displaying a message when `HeroService` fetches heroes successfully

### Create `MessagesComponent`

Use `ng generate` to create the `MessagesComponent`.

```bash
ng generate component messages
```

`ng generate` creates the component files in the `src/app/messages` directory and declares the `MessagesComponent` in `AppModule`.

Edit the `AppComponent` template to display the `MessagesComponent`.

{% tabs %}
{% tab title="src/app/app.component.html" %}

```html
<h1>{{title}}</h1>
<app-heroes />
<app-messages />
```

{% endtab %}
{% endtabs %}

You should see the default paragraph from `MessagesComponent` at the bottom of the page.

### Create the `MessageService` <a href="#create-the-messageservice" id="create-the-messageservice"></a>

Use `ng generate` to create the `MessageService` in `src/app`.

```bash
ng generate service message
```

Open `MessageService` and replace its contents with the following.

{% tabs %}
{% tab title="src/app/message.service.ts" %}

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

@Injectable({
  providedIn: 'root',
})
export class MessageService {
  messages: string[] = [];

  add(message: string) {
    this.messages.push(message);
  }

  clear() {
    this.messages = [];
  }
}
```

{% endtab %}
{% endtabs %}

The service exposes its cache of `messages` and two methods:

* One to `add()` a message to the cache.
* Another to `clear()` the cache.

### Inject it into the `HeroService` <a href="#inject-it-into-the-heroservice" id="inject-it-into-the-heroservice"></a>

In `HeroService`, import the `MessageService`.

{% tabs %}
{% tab title="src/app/hero.service.ts (import MessageService)" %}

```typescript
import { MessageService } from './message.service';
```

{% endtab %}
{% endtabs %}

Declares a private `messageService` property. Angular injects the singleton `MessageService` into that property when it creates the `HeroService`.

{% tabs %}
{% tab title="src/app/hero.service.ts" %}

```typescript
private messageService = inject(MessageService);
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
This is an example of a typical *service-in-service* scenario in which you inject the `MessageService` into the `HeroService` which is injected into the `HeroesComponent`.
{% endhint %}

### Send a message from `HeroService` <a href="#send-a-message-from-heroservice" id="send-a-message-from-heroservice"></a>

Edit the `getHeroes()` method to send a message when the heroes are fetched.

{% tabs %}
{% tab title="src/app/hero.service.ts" %}

<pre class="language-typescript"><code class="lang-typescript"><strong>getHeroes(): Observable&#x3C;Hero[]> {
</strong>  const heroes = of(HEROES);
  this.messageService.add('HeroService: fetched heroes');
  return heroes;
}
</code></pre>

{% endtab %}
{% endtabs %}

### Display the message from `HeroService` <a href="#display-the-message-from-heroservice" id="display-the-message-from-heroservice"></a>

The `MessagesComponent` should display all messages, including the message sent by the `HeroService` when it fetches heroes.

Open `MessagesComponent` and import the `MessageService`.

{% tabs %}
{% tab title="src/app/messages/messages.component.ts (import MessageService)" %}

```typescript
import { MessageService } from '../message.service';
```

{% endtab %}
{% endtabs %}

Declare a **public** `messageService` property. Angular injects the singleton `MessageService` into that property when it creates the `MessagesComponent`.

{% tabs %}
{% tab title="src/app/messages/messages.component.ts" %}

```typescript
public messageService = inject(MessageService);
```

{% endtab %}
{% endtabs %}

The `messageService` property **must be public** because you're going to bind to it in the template.

{% hint style="warning" %}
Angular only binds to *public* component properties.
{% endhint %}

### Bind to the `MessageService`

Replace the `MessagesComponent` template created by `ng generate` with the following.

{% tabs %}
{% tab title="src/app/messages/messages.component.html" %}

```html
@if (messageService.messages.length) {
  <div>
    <h2>Messages</h2>
    <button type="button" class="clear" (click)="messageService.clear()">
      Clear messages
    </button>
    @for (message of messageService.messages; track message) {
      <div>{{ message }}</div>
    }
  </div>
}
```

{% endtab %}
{% endtabs %}

This template binds directly to the component's `messageService`.

|                                                                     | DETAILS                                                        |
| ------------------------------------------------------------------- | -------------------------------------------------------------- |
| `@if`                                                               | Only displays the messages area if there are messages to show. |
| `@for`                                                              | Presents the list of messages in repeated `<div>` elements.    |
| Angular [event binding](https://v16.angular.io/guide/event-binding) | Binds the button's click event to `MessageService.clear()`.    |

The messages look better after you add the private CSS styles to `messages.component.css` as listed in one of the ["final code review"](https://v16.angular.io/tutorial/tour-of-heroes/toh-pt4#final-code-review) tabs below.

## Add MessageService to HeroesComponent

The following example shows how to display a history of each time the user clicks on a hero. This helps when you get to the next section on Routing.

{% tabs %}
{% tab title="src/app/heroes/heroes.component.ts" %}

```typescript
import { Component, OnInit } from '@angular/core';

import { Hero } from '../hero';
import { HeroService } from '../hero.service';
import { MessageService } from '../message.service';

@Component({
  selector: 'app-heroes',
  templateUrl: './heroes.component.html',
  styleUrls: ['./heroes.component.css'],
  standalone: true
})
export class HeroesComponent implements OnInit {
  selectedHero?: Hero;
  heroes: Hero[] = [];
  
  private heroService = inject(HeroService);
  private messageService = inject(MessageService);

  ngOnInit(): void {
    this.getHeroes();
  }

  onSelect(hero: Hero): void {
    this.selectedHero = hero;
    this.messageService.add(`HeroesComponent: Selected hero id=${hero.id}`);
  }

  getHeroes(): void {
    this.heroService.getHeroes()
        .subscribe(heroes => this.heroes = heroes);
  }
}
```

{% endtab %}
{% endtabs %}

Refresh the browser to see the list of heroes, and scroll to the bottom to see the messages from the HeroService. Each time you click a hero, a new message appears to record the selection. Use the **Clear messages** button to clear the message history.

## Final code review

Here are the code files discussed on this page.

{% tabs %}
{% tab title="src/app/hero.service.ts" %}

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

import { Observable, of } from 'rxjs';

import { Hero } from './hero';
import { HEROES } from './mock-heroes';
import { MessageService } from './message.service';

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

  private messageService = inject(MessageService);

  getHeroes(): Observable<Hero[]> {
    const heroes = of(HEROES);
    this.messageService.add('HeroService: fetched heroes');
    return heroes;
  }
}

```

{% endtab %}

{% tab title="src/app/message.service.ts" %}

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

@Injectable({
  providedIn: 'root',
})
export class MessageService {
  messages: string[] = [];

  add(message: string) {
    this.messages.push(message);
  }

  clear() {
    this.messages = [];
  }
}

```

{% endtab %}

{% tab title="src/app/heroes/heroes.component.ts" %}

```typescript
import { Component, OnInit } from '@angular/core';

import { Hero } from '../hero';
import { HeroService } from '../hero.service';
import { MessageService } from '../message.service';

@Component({
  selector: 'app-heroes',
  templateUrl: './heroes.component.html',
  styleUrls: ['./heroes.component.css'],
  standalone: true
})
export class HeroesComponent implements OnInit {
  selectedHero?: Hero;
  heroes: Hero[] = [];
  
  private heroService = inject(HeroService);
  private messageService = inject(MessageService);

  ngOnInit(): void {
    this.getHeroes();
  }

  onSelect(hero: Hero): void {
    this.selectedHero = hero;
    this.messageService.add(`HeroesComponent: Selected hero id=${hero.id}`);
  }

  getHeroes(): void {
    this.heroService.getHeroes()
        .subscribe(heroes => this.heroes = heroes);
  }
}

```

{% endtab %}

{% tab title="src/app/messages/messages.component.ts" %}

```typescript
import { Component } from '@angular/core';
import { MessageService } from '../message.service';

@Component({
  selector: 'app-messages',
  templateUrl: './messages.component.html',
  styleUrls: ['./messages.component.css'],
  standalone: true
})
export class MessagesComponent {

  public messageService = inject(MessageService);

}
```

{% endtab %}

{% tab title="src/app/messages/messages.component.html" %}

```html
@if (messageService.messages.length) {
  <div>
    <h2>Messages</h2>
    <button type="button" class="clear" (click)="messageService.clear()">
      Clear messages
    </button>
    @for (message of messageService.messages; track message) {
      <div>{{ message }}</div>
    }
  </div>
}
```

{% endtab %}

{% tab title="src/app/messages/messages.component.css" %}

```scss
/* MessagesComponent's private CSS styles */
h2 {
  color: #A80000;
  font-family: Arial, Helvetica, sans-serif;
  font-weight: lighter;
}

.clear {
  color: #333;
  background-color: #eee;
  margin-bottom: 12px;
  padding: 1rem;
  border-radius: 4px;
  font-size: 1rem;
}
.clear:hover {
  color: white;
  background-color: #42545C;
}
```

{% endtab %}

{% tab title="src/app/app.component.html" %}

```html
<h1>{{title}}</h1>
<app-heroes />
<app-messages />
```

{% endtab %}
{% endtabs %}

## Summary

* You refactored data access to the `HeroService` class.
* You registered the `HeroService` as the *provider* of its service at the root level so that it can be injected anywhere in the application.
* You used [Angular Dependency Injection](https://v16.angular.io/guide/dependency-injection) to inject it into a component.
* You gave the `HeroService` `get data` method an asynchronous signature.
* You discovered `Observable` and the RxJS `Observable` library.
* You used RxJS `of()` to return `Observable<Hero[]>`, an observable of mock heroes.
* The component's `ngOnInit` lifecycle hook calls the `HeroService` method, not the constructor.
* You created a `MessageService` for loosely coupled communication between classes.
* The `HeroService` injected into a component is created with another injected service, `MessageService`.

## → Hier geht es weiter

{% content-ref url="/pages/EihZ6YJxtO2BQnhiCkZu" %}
[Hinweise zu Kapitel 4](/tag-1/tour-of-heroes/4.-add-services/hinweise-zu-kapitel-4.md)
{% endcontent-ref %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://m335.ict-bz.ch/tag-1/tour-of-heroes/4.-add-services.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
