Open In App

How to Subscribe to an Observable in Angular?

In Angular, managing data streams effectively is important, especially when dealing with asynchronous operations. Observables, a core part of the RxJS library used in Angular, are powerful tools for handling these data streams. In this article, we will explore how to subscribe to Observables in Angular.

What is an Observable?

An Observable is a mechanism in RxJS used to handle asynchronous data streams, like HTTP requests, user input, etc. Observables are lazy, which means they won’t start emitting data until you subscribe to them.

How to Subscribe to an Observable?

Subscribing to an Observable means starting to listen to the stream it provides. When you subscribe, you provide functions that will be executed when the Observable emits a value, an error, or completes. Let's see how this is done with a basic example.

Steps to Create the Project

Step 1: Create a new angular project by using the following command.

ng new project-name

Step 2: Go inside the project

cd project-name

Step 3: Use the following command to start the application.

ng serve

Import HttpClientModule in the app.module.ts like below.

imports: [BrowserModule, AppRoutingModule, HttpClientModule]

And remove the auto generated HTML code form app.compoent.html

Step 4: Create a new service file inside app component using the following command.

ng g s userService

Folder Structure:

Screenshot-2024-04-26-071434

Dependencies:

"dependencies": {
"@angular/animations": "^16.1.0",
"@angular/common": "^16.1.0",
"@angular/compiler": "^16.1.0",
"@angular/core": "^16.1.0",
"@angular/forms": "^16.1.0",
"@angular/platform-browser": "^16.1.0",
"@angular/platform-browser-dynamic": "^16.1.0",
"@angular/router": "^16.1.0",
"rxjs": "~7.8.0",
"tslib": "^2.3.0",
"zone.js": "~0.13.0"
}

Approach

Examples:

Example 1: Fetching Data with HTTP

Imagine you have a service in Angular that fetches users data from an API using the HttpClient module. In this example I am using a dummy API service to fetch the User data.

<!-- app.component.ts -->

<h1 style="color: green">GeeksforGeeeks</h1>
<br />
<div style="
    border: 1px black solid;
    border-radius: 8px;
    padding: 10px;
    width: 500px;
  ">
    <p>firstName:&nbsp; {{ usersData["firstName"] }}</p>
    <p>lastName:&nbsp; {{ usersData["lastName"] }}</p>
    <p>email:&nbsp; {{ usersData["email"] }}</p>
</div>
//app.component.ts

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

@Component({
    selector: 'app-root',
    templateUrl: './app.component.html',
    styleUrls: ['./app.component.scss'],
})
export class AppComponent {
    title = 'geeks';
    usersData: any = {};
    constructor(private userService: UserService) {
        this.getUserData();
    }

    getUserData() {
        this.userService.getUsers().subscribe({
            next: (data) => {
                this.usersData = data;
            },
            error: (error) => {
                console.error('Error fetching user:', error);
            },
        });
    }
}
//userService.ts

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';

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

    constructor(private http: HttpClient) { }

    getUsers(): Observable<any> {
        return this.http.get(this.apiUrl);
    }
}

This component subscribes to the Observable returned by getUserData() and updates the userData variable with the data received.

The subscription is set up with an object containing next and error handlers:

Output:

Screenshot-2024-04-21-145727

Example 2: Subscriptions with RxJS Operators

RxJS operators allow you to manipulate data streams. For example, you might want to filter or map data as it comes through the stream before it reaches the subscription. Let's see an example to include some operators:

<!-- app.component.html -->

<h1 style="color: green">GeeksforGeeeks</h1>
<br />
<div style="
    border: 1px black solid;
    border-radius: 8px;
    padding: 10px;
    width: 500px;
  ">
    <div *ngFor="let item of usersData">
        <p>firstName:&nbsp; {{ item["firstName"] }}</p>
        <p>lastName:&nbsp; {{ item["lastName"] }}</p>
        <p>gender:&nbsp; {{ item["gender"] }}</p>
        <br />
        <hr />
    </div>
</div>
//app.component.ts 

import { Component } from '@angular/core';
import { UserService } from './user.service';
import { catchError, map, of } from 'rxjs';

@Component({
    selector: 'app-root',
    templateUrl: './app.component.html',
    styleUrls: ['./app.component.scss'],
})
export class AppComponent {
    title = 'geeks';
    usersData: any = [];
    constructor(private userService: UserService) {
        this.getUserData();
    }

    getUserData() {
        this.userService
            .getUsers()
            .pipe(
                map((users) =>
                    users['users'].filter((user: any) => user['gender'] === 'male')
                ),
                catchError((error) => {
                    console.error('Error fetching users:', error);
                    return of([]);
                })
            )
            .subscribe({
                next: (data) => {
                    this.usersData = data;
                },
                error: (error) => {
                    console.error('Error fetching user:', error);
                },
            });
    }
}
//userService.ts

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';

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

    constructor(private http: HttpClient) { }

    getUsers(): Observable<any> {
        return this.http.get(this.apiUrl);
    }
}

Output:

Screenshot-2024-04-21-170646

Article Tags :