In Angular, both observables and promises are used for handling asynchronous operations. They provide a way to work with asynchronous data and handle the completion or failure of the operation. However, there are some differences between observables and promises:
Promises
- Promises are part of the JavaScript language and are available natively in most modern browsers.
- A promise represents a single future value or the result of an asynchronous operation.
- Promises can be in one of three states: pending, fulfilled, or rejected.
- Promises are eager, meaning that once a promise is created, it immediately starts executing.
- Promises are chainable using
.then()
and.catch()
methods to handle the resolved value or catch any errors. - Promises are not cancelable by default.
Observables
- Observables are part of the RxJS library, which provides a reactive programming paradigm for handling asynchronous operations.
- An observable represents a stream of values over time, allowing you to work with multiple values asynchronously.
- Observables can emit multiple values and can also emit an error or completion signal.
- Observables are lazy, meaning they do not start executing until someone subscribes to them.
- Observables provide powerful operators to transform, combine, and manipulate the emitted values over time.
- Observables are cancelable by unsubscribing from the subscription, which allows for resource cleanup and prevents memory leaks.
When to use Promises:
- When you have a single asynchronous operation that will produce a single result or error.
- When you need a simpler and more straightforward way to handle asynchronous operations.
When to use Observables:
- When you have multiple asynchronous operations or want to work with streams of values.
- When you need more advanced capabilities such as operators for transforming and manipulating data over time.
- When you want to take advantage of the reactive programming paradigm and its benefits.
In Angular, both Promises and Observables are widely used. Promises are commonly used with HTTP requests, while Observables are used for handling more complex scenarios such as event streams, real-time data, or when using reactive forms.
It’s important to note that you can convert a Promise to an Observable using the from()
function in RxJS, and vice versa using the toPromise()
method available on Observables.
Example promises Mythology
Import the necessary modules:
Here’s an example of how to use a Promise in Angular, specifically with an HTTP request using the Angular HttpClient
module:
1 2 | import { HttpClient } from '@angular/common/http'; import { Injectable } from '@angular/core'; |
Create a service that performs an HTTP request using a Promise:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | @Injectable({ providedIn: 'root' }) export class DataService { constructor(private http: HttpClient) {} fetchData(): Promise<any> { return new Promise((resolve, reject) => { this.http.get('https://api.example.com/data') .subscribe( (response) => { resolve(response); }, (error) => { reject(error); } ); }); } } |
Use the Promise in a component:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | import { Component } from '@angular/core'; import { DataService } from './data.service'; @Component({ selector: 'app-my-component', template: ` <button (click)="getData()">Get Data</button> <div *ngIf="data">{{ data | json }}</div> ` }) export class MyComponent { data: any; constructor(private dataService: DataService) {} getData() { this.dataService.fetchData() .then((response) => { this.data = response; }) .catch((error) => { console.error(error); }); } } |
In the above example, we created a DataService
that makes an HTTP GET request to retrieve data from an API. The fetchData()
method returns a Promise that resolves with the response data or rejects with an error if the request fails.
Then, in the MyComponent
component, we inject the DataService
and use the getData()
method to call the service and handle the Promise. When the “Get Data” button is clicked, the getData()
method is called, which triggers the HTTP request. Once the Promise is resolved, we assign the response data to the data
property, and it is displayed in the template using Angular’s *ngIf
directive.
Remember to import the necessary modules and provide the DataService
in the appropriate module to make it available for dependency injection.
This is a basic example of using Promises in Angular for making HTTP requests, but Promises can be used in various other scenarios where you have asynchronous operations that produce a single result.
Example Observables Mythology
Here’s an example of how to use Observables in Angular, specifically with an HTTP request using the Angular HttpClient
module:
Import the necessary modules:
1 2 3 | import { HttpClient } from '@angular/common/http'; import { Injectable } from '@angular/core'; import { Observable } from 'rxjs'; |
Create a service that performs an HTTP request using an Observable:
1 2 3 4 5 6 7 8 9 10 | @Injectable({ providedIn: 'root' }) export class DataService { constructor(private http: HttpClient) {} fetchData(): Observable<any> { return this.http.get('https://api.example.com/data'); } } |
Use the Observable in a component:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | import { Component } from '@angular/core'; import { DataService } from './data.service'; @Component({ selector: 'app-my-component', template: ` <button (click)="getData()">Get Data</button> <div *ngIf="data">{{ data | json }}</div> ` }) export class MyComponent { data: any; constructor(private dataService: DataService) {} getData() { this.dataService.fetchData() .subscribe( (response) => { this.data = response; }, (error) => { console.error(error); } ); } } |
In the above example, we created a DataService
that makes an HTTP GET request to retrieve data from an API. The fetchData()
method returns an Observable that emits the response data.
Then, in the MyComponent
component, we inject the DataService
and use the getData()
method to call the service and handle the Observable. When the “Get Data” button is clicked, the getData()
method is called, which triggers the HTTP request. We subscribe to the Observable and provide callback functions for handling the emitted data and any errors.
Once the response data is emitted by the Observable, we assign it to the data
property, and it is displayed in the template using Angular’s *ngIf
directive.
Remember to import the necessary modules and provide the DataService
in the appropriate module to make it available for dependency injection.
Observables offer powerful features such as operators for transforming, combining, and manipulating data over time. They are especially useful when dealing with streams of values or handling asynchronous operations that may emit multiple values or errors.
This is a basic example of using Observables in Angular for making HTTP requests, but Observables can be used in various other scenarios where you need to handle asynchronous operations and streams of data.