Published: September 19 2020

RxJS - Wait for Promise to resolve with Observable

This is a quick example showing how to wait for Promises to resolve with RxJS Observables, so that an Observable waits for a promise to resolve before emitting the next value or executing the next pipe() operator.

The example shows five observable values that get emitted in sequence, each waiting two seconds for a Promise to resolve. It's built with Angular but the RxJS code isn't Angular specific and could be used with any front end framework (e.g. React, Vue etc).

Here it is in action: (See on StackBlitz at https://stackblitz.com/edit/rxjs-wait-for-promise-to-resolve-with-observable)


Example app component with observables waiting for promises

The app component creates an observable sequence containing five string values using the RxJS of() function.

The observable values are piped through two concatMap() operators before being pushed to the users array in the subscribe() method to be rendered in the UI.

RxJS concatMap operator

The concatMap() operator is used in the example to convert promises into observables by passing it a function that returns a Promise. The concatMap() operator runs each observable in sequence and waits for the previous observable to complete before continuing to the next one, if a Promise is returned in concatMap() then it will wait for the promise to resolve before completing the observable.

NOTE: It's also possible to convert a Promise to an Observable with the RxJS from() operator, e.g. from(new Promise(resolve => setTimeout(() => resolve(value), 2000));).

import { Component } from '@angular/core';
import { of } from 'rxjs'; 
import { concatMap } from 'rxjs/operators';

@Component({ selector: 'app', templateUrl: 'app.component.html' })
export class AppComponent {
    values = [];

    constructor() {
        // create observable that emits five values
        const observable = of('Value 1', 'Value 2', 'Value 3', 'Value 4', 'Value 5');

        observable
            .pipe(concatMap(value => {
                console.log(`${value}: first pipe operator (before promise)`);                
                // return a promise that resolves with the specified value after 2 seconds
                return new Promise(resolve => setTimeout(() => resolve(value), 2000));
            }))
            .pipe(concatMap(value => {
                console.log(`${value}: second pipe operator (after promise resolved)`);
                return of(value);
            }))
            .subscribe(value => this.values.push(value));
    }    
}


Example app component template

For completeness this is the example Angular app component that renders the observable values after the promises are resolved.

<h3 class="p-3 text-center">RxJS - Wait for Promise to resolve with Observable</h3>
<div class="container">
    <table class="table table-striped table-bordered">
        <thead>
            <tr>
                <td>Observable values returned every two seconds from promises:</td>
            </tr>
        </thead>
        <tbody>
            <tr *ngFor="let value of values">
                <td>{{value}}</td>
            </tr>
        </tbody>
    </table>
</div>

 


Need Some RxJS Help?

Search fiverr for freelance RxJS developers.


Follow me for updates

On Twitter or RSS.


When I'm not coding...

Me and Tina are on a motorcycle adventure around Australia.
Come along for the ride!


Comments


Supported by