How do use Angular promises with an example?

Javascript Promises are another way of handling asynchronous operations in Angular. We don’t have an Angular promise library like the rxjs library for observable which is integrated within Angular API. Promises were introduced in ES2015 to solve the callback hell problem and promises are progressive succession in asynchronous programming.

In this tutorial, we’ll learn about JavaScript Promises, how we can used it in our Angular project. We have example of promise to fetch data from remote server and how to use Angular promise all.

What is an angular promise?

When working with asynchronous operations like an HTTP request and we don’t know how much time it will take to get a response from the server. The Javascript by default is synchronous, blocking, and single-threaded language. This means the Javascript engine can only process one code at a time in a single thread. When a thread is blocked we can’t execute other code that is also blocked, this makes JS slow and inability to execute multiple operations.

Asynchronous make our code nonblocking, allowing us to execute multiple codes at the same time. In Angular, we can achieve asynchronous using the following method.

  1. Callback function
  2. The promise from Javascript can be used in Angular.
  3. Observable using Rxjs library in Angular: Library for reactive programming using Observables.
Promise: Promises which are a more powerful abstraction for writing asynchronous code, We can used Javascript Promise object in our Angular project.

While asynchronous operation, code can move to the next line by allowing UI remains responsive and the user continues working application while asynchronous operations like HTTP requests are being processed in the background. The asynchronous program allows us to move to the next line of code before the task finishes.

Promise in Javascript represents a piece of task that is wrapped in asynchronous operation and notified whenever the asynchronous operation is completed or failed at some point in the future. Whenever a promise is run there are two possible outcomes from a promise, either promise is completed or failed.

Using async and await keyword with promise make it easy to read, write, and we can also use try and catch for error handling with (async & await).

Promise can have one of three states as follows.

  1. Pending: initial state, neither fulfilled nor rejected.
  2. Fulfilled: The promise operation was successfully completed.
  3. Rejected: Promise failed to complete because an error occurs during promise execution.

When to use promise in Angular?

In Angular we have the Rxjs library, in most cases, we used Observable to perform an asynchronous operation. Angular uses Rx.js which is Observables instead of promises for dealing with HTTP operations.

Promises are good for single event cases if you still want to use promises in Angular. There are certain cases we use promise.

  1. While working with fetch API, we can use fetch API to retrieve local JSON data or remote also. Angular HTTPClienModule uses observable to fetch remote data.
  2. In the @angular/fire/firestore we can use both promise and observable.
  3. We can convert observable to promise and then handled it in Angular but is recommended to use observable.

If you know some other case where we can use promise, please add a note in the comments section.


Angular promise example

Let’s demonstrate the Angular promise example using fetch API. We can use fetch API from window object to make networks requests. The fetch API is promise-based, we can use it to retrieve data from local or remote servers. Here we are using fetch API to get todos data from https://jsonplaceholder.typicode.com/todos

Angular promise example
Angular promise example

We have used bootstrap Framework to display our above table UI, if you want to learn how to add bootstrap UI in our angular project then check previous articles on bootstrap.

Let’s add fetch API to retrieve todos data

In the app.component.ts file let’s add fetch API to retrieve the above JSON data from our remote server jsonplaceholder.typicode.com.

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

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss'],
})
export class AppComponent implements OnInit {
  URL = 'https://jsonplaceholder.typicode.com/todos';
  todos: any = [];

  constructor() {}

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

  async getTodos() {
    try {
      this.todos = await (await fetch(this.URL)).json();
    } catch (err) {
      console.log(err);
    }
  }
}

Without async and await, we can call promise by using then method on promise object as below.

fetch(this.URL).then((data) => {
   //promise success
}, err => {
  //promise error
})

Using async and await with promise makes our asynchronous promise code easier to read and understand. We can add try and catch with promise when we use async and await with promise.

Displaying our todos JSON in our component template

Once we have todos JSON data, we can display it in our component, in our case let’s display it in the app.component.html file.

<div class="container">
  <table class="table table-striped">
    <thead>
      <tr>
        <th scope="col">#</th>
        <th scope="col">Title</th>
        <th scope="col">Status</th>
      </tr>
    </thead>
    <tbody *ngIf="todos">
      <tr *ngFor="let todo of todos; index as i">
        <th scope="row">{{ i + 1 }}</th>
        <td>{{ todo.title }}</td>
        <td>{{ todo.completed }}</td>
      </tr>
    </tbody>
  </table>
</div>

<router-outlet></router-outlet>
Note: Above example of retrieving data from remote server, can achieve using observable along with HttpClientModule, is recommended approach from Angular. The Angular HttpClient object makes a request to a URL, the response comes back as Observable , and the client’s code can handle it either by using the subscribe() method or with the async pipe.

Creating promise in Angular

In Javascript, we can easily create promises by instantiating a new keyword on the Promise class. The new Promise object receives a single function as a parameter (known as the executor function), which inturns take two arguments. The first argument resolve() function is called whenever a promise is successfully completed, and the second argument reject() function is called when a promise fails its operation.

The syntax of new promise

Promise(executorCallback(resolve, reject));
const promiseObject = new Promise((resolve, reject) => {
    // Do something asynchronously
   if (success) {
      resolve(value);
   } else {
      reject(error);
   }
});

Angular promise all

The promise.all() is Javascript static class function and Promise all is not instantiated on calling new on Promise class. When multiple promises need to be run, if the order does not matter, then it is best to use Promise.all() instead of using async and await with promise.

The Promise.all(): It waits for all promises to be resolved, or for any to be rejected. Promise.all() takes in an array of promises and when all of the promises have been resolved, the then handler will be called.

Promise.all([promise1, promise2, promise3])
 .then(results => console.log(results))
 .catch(err => console.log(err));

OR
const [data1, data2, data3] = await Promise.all([promise1, promise2, promise3])

We have three promise when all promise is handled successfully, then the handler function is called and the result of then is an array with value resolved from all the above three promise. Let’s demonstrate an example.

const promise1 = new Promise((resolve, reject) => 
    setTimeout(() => resolve('Promise 1'), 1000));

const promise2 = new Promise((resolve, reject) => 
    setTimeout(() => resolve('Promise 2'), 2000));

const promise3 = new Promise((resolve, reject) => 
    setTimeout(() => resolve('Promise 3'), 300));

Promise.all([promise1, promise2, promise3])
  .then(results => console.log(results));

The output of the above three promise results is an array containing resolve values from promises.

Angular  promise all example

Sometimes data we get from API might have dependent on other tables or collections of remote databases, then we might use an array of promises and resolve using the Promise.all. Where courses are the list of courses taken by a student, once we have courses, we get individual courses using promise.all

// Already got courses data from server to get details of individual course
getCoursesInfo(courses:Course[]) {
    const coursesPromises = courses.map((course: any, index) =>
        new Promise<void>((resolve) => {
          this.courseService.getCourseByID(course.id)
            .subscribe((course) => {
               // ... Some operation
              resolve();
            });
        })
    );

    Promise.all(coursesPromises).then(() => {
      //... after all promise successful run
    });
  }

Let’s add another fetch to retrieve user’s data from a server, we can combine these two promises in Angular promise.all as below.

....
export class AppComponent implements OnInit {
  URL = 'https://jsonplaceholder.typicode.com/todos';
  URLUser = 'https://jsonplaceholder.typicode.com/users';
  todos: any = [];
  users: any = [];

  constructor() {}

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

  async getTodosAndUsers() {
    let todosData = await (await fetch(this.URL)).json();
    let postsData = await (await fetch(this.URLUser)).json();

    Promise.all([todosData, postsData]).then((response) => {
      this.todos = response[0];
      this.users = response[1];
    });
  }
}
Angular promise all

Related posts

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top