Getting Started with Service with a Subject in Angular

A powerful technique in Angular is the built in integration with RxJS. Making use of reactive programming (ie. RxJS) can remove a lot of code from your Angular application. This is an indictor that reactive programming takes care of a lot of the logic you would otherwise have to come up with and test yourself.

There are simple steps you can take to get started with writing reactive Angular applications. You can then use the understanding and confidence you get from the simple steps to start using reactive programming in other, more complicated cases.

Simple Service with a Subject

The following code is a simple Angular service with a subject.
name.service.ts

// name.service.ts
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { BehaviorSubject, Observable } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class NameService {
  private mName$ = new BehaviorSubject<string>(null);

  name$(): Observable<string> {
    return this.mName$;
  }

  constructor(private httpClient: HttpClient) { }

  loadName() {
    this.httpClient.get<string>('name URL')
      .subscribe(name => this.mName$.next(name));
  }
}

There are 3 pieces to the subject that come together to trigger getting the name from the API and passing on the retrieved name.

API Call

The entry point for a user of the service is the loadName function on line 18. It triggers the HTTP call to the API and passes on the retrieved name to mName$ in the subscribe call on line 20.

Storing the Retrieved Name

The mName$ member variable on line 10 of the service is used as private intermediate storage of the name retrieved from the API in the service. mName$ is tightly linked to the name$ function which is used to control access to the intermediate storage.

Passing on the Retrieved Name

The name$ function of the service is used to pass on the name retrieved from the API on line 12. Hiding the private intermediate storage mName$ behind the name$ function allows control over how the name is distributed throughout the Angular application.

The next step is to show the name in a component.

Reactive Component

Once the name has been retrieved from the API, the next step is to show it in a component.

Component Typescript Code

The following is the typescript code for the component.
name.component.ts

// name.component.ts
import { Component, OnInit } from '@angular/core';

import { NameService } from './name.service';

@Component({
  selector: 'app-name',
  templateUrl: './name.component.html',
  styleUrls: ['./name.component.css']
})
export class NameComponent implements OnInit {
  constructor(public nameService: NameService) { }

  ngOnInit() {
    this.nameService.loadName();
  }

}

There is hardly any code in the component that is not part of the required Angular component code. The only line that has been added is line 15 which instructs the service to load the name along with importing the service on line 4 and injecting it into the component on line 12.

Component Template

The following is the HTML template associated with the component.
name.component.html

<!-- name.component.html -->
<ng-container *ngIf="nameService.name$() | async as name">
  {{ name }}
</ng-container>

In the template the name$ function of the service is passed to the async pipe on line 2. The values emitted by the name$ observable are renamed to the name variable and then displayed on line 3.

That concludes the simple example for making use of a subject with a service. There are some additions to consider depending on the use case. For example, you may want to introduce error handling in the subject. You may also want to write tests for the service and the component.

3 thoughts on “Getting Started with Service with a Subject in Angular

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s