What is the best way to ensure observables in a template (using async pipe) are fully subscribed to before executing any initialization code?

I am facing an issue with my HTTP service that returns information based on a given item ID. The data is fetched using a Subject, which receives the initial data in the ngOnInit method.

To display the returned data in the HTML, I utilize the async pipe.

The problem arises when the async pipe has not subscribed to the observables before I call selections.next with the first item ID, causing it not to be displayed during initialization.

Is there a way to ensure that the async pipe subscribes to the Observable before sending the initial data to the subject for the first HTTP request?

I have experimented with various lifecycle hooks, but none seem to resolve the issue.

import { Component, OnInit } from "@angular/core";
import { Observable } from "rxjs/Observable";
import { Subject } from "rxjs/Subject";

import { ExampleService } from "./example.service";

import "rxjs/add/operator/switchMap";

@Component({
  template: `
    <div>
      <div *ngFor="let time of times | async">{{ time }}</div>
    </div>
  `,
})
export class ExampleComponent implements OnInit {

  times: Observable<string[]>;

  constructor(
    private exampleService: ExampleService
  ) { }

  ngOnInit() {

    var itemIds = new Subject<number>();

    this.times = itemIds
      .switchMap(itemId => this.exampleService.getData(itemId))
      .map(data => this.calculateTimes(data));

    // Provide an item ID to the subject.
    // This is also performed periodically as well as
    // during initialization.
    itemIds.next(10);
  }

  calculateTimes(data: string[]) {
    /*
     * Some processing code.
    */

    return data;
  }
}

Answer №1

Consider using a behavior subject in place of a regular subject.

A behavior subject retains its last value and transmits it to new subscribers upon subscription.

import { BehaviorSubject } from "rxjs/BehaviorSubject";


var itemIds = new BehaviorSubject<number>(null);

Initializing the behavior subject with a value is necessary. It helps address timing issues when you are uncertain which will come first, your value or your subscriber.

To prevent duplicate calls, you can implement a local store pattern:

times: BehaviorSubject<string[]> = new BehaviorSubject<string[]>();


var itemIds = new Subject<number>();

itemIds.switchMap(itemId => this.exampleService.getData(itemId))
    .map(data => this.calculateTimes(data)).subscribe(this.times);

This approach ensures that the only subscriber to the HTTP call is the behavior subject that you subscribe to in the template.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What is the best way to efficiently test multiple requests in a pipeline using Angular?

Looking to test three requests made within a pipeline. Here's a simplified example: httpClient.get<Data[]>(testUrl) .pipe( mergeMap(() => range(0, 2)), mergeMap(() => httpClient.get<Data[]>(testUrl)), ...

Bring in exclusively typescript module declarations

In my various React projects, I find myself constantly declaring the same typescript modules, such as fonts.d.ts: declare module "*.woff"; declare module "*.woff2"; or images.d.ts: declare module "*.jpg" { const src: string ...

The Viewchild element is currently nonexistent

(Angular 9) I'm having issues with using ViewChield() in my code. Here is a snippet of the HTML I am working with: <input type="text" pInputText [(ngModel)]="code" #inputStudent/> Here is what I have in my TypeScript file: ...

The "fullName" input remains constant despite any changes made during text input

Currently, I am in the process of implementing a ControlValueAccessor in a child form. In my setup, there is a parent form group and control structured like this: this.form = this.formBuilder.group({ user: ['', Validators.required] ...

Tips for boosting ViteJs development mode performance

One issue I am facing is the slow server performance during development mode. After starting the server and opening the page in my browser, I have to wait 3–6 minutes for it to load! Initially, ViteJs downloads a small amount of resources, but then the ...

converting HTML values to TypeScript

I'm a beginner with Angular and could use some assistance. Currently, I have two components - one for the index and another for navigation. Within the index component, there are subcomponents that change based on the value of a variable called produ ...

Secure method of utilizing key remapped combined type of functions

Imagine having a union type called Action, which is discriminated on a single field @type, defined as follows: interface Sum { '@type': 'sum' a: number b: number } interface Square { '@type': 'square&apos ...

What is the best method for incorporating Angular 2 files into a Django template?

My application structure is set up like this: ├── project | |── templates │ │ └── index.html │ ├── __init__.py │ ├── models.py │ ├── urls.py │ ├── serializers.py │ ├── views.py ...

How can I determine the appropriate data type for 'this' when utilizing TypeScript in conjunction with DataTables?

I found some code on a page I visited: https://datatables.net/reference/api/columns().every() Here is the specific code snippet I am using: var table = $('#example').DataTable(); table.columns().every( function () { var that = this; ...

Expiry Time for JWT Token (ASP.NET Core)

I've been trying to extend the lifespan of JWT tokens without success. After researching online, I came across information about JwtBearerOptions.TokenValidationParameters.ClockSkew. I attempted to set timespans of 1 minute and 20 seconds, but the a ...

Angular 2 or more variable binding

In this demonstration, only the unit-object will be saved: <select id="unit" name="unit" #unit="ngModel" class="form-control" [(ngModel)]="iu.unit" (change)="onDropdownChangeUnit($event)"> <option *ngFor="let i of UI_Units" [ngV ...

Allow only specified tags in the react-html-parser white list

Recently, I've been working on adding a comments feature to my projects and have come across an interesting challenge with mentioning users. When creating a link to the user's profile and parsing it using React HTML parser, I realized that there ...

Troubleshooting form submission issues in Angular 4

I am encountering a few issues with my search form. It is supposed to function as a search tool with one input field and one button. However, something seems amiss. I am utilizing an API that returns values based on the string inputted. When an empty value ...

Ensure that you are completely logged out of all browser tabs when one tab has been successfully logged out

Just started working with Angular 4 and have built an application with a login page and home page. Upon successful login, I navigate to the home page. I noticed that if my application is open in multiple tabs and I log out from one tab, clicking on any ot ...

In Typescript 12, the process of creating a Bootstrap popup that waits for the user to click on a value entered in

Greetings! I am currently working with Angular TypeScript 12 and I am attempting to trigger a Bootstrap modal popup when I enter a code in the input field and press enter. However, the issue is that the popup is always displayed even without typing anythin ...

Unable to establish a connection with the server data in pusher.js

I have been trying to set up a collaborative drawing application by following this tutorial. Although I have managed to run the application, the collaborative drawing feature is not working as expected. I have correctly configured the PUSHER_APP_ID, PUSHER ...

Is there cause for worry regarding the efficiency issues of utilizing Object.setPrototypeOf for subclassing Error?

My curiosity is piqued by the Object.setPrototypeOf(this, new.target.prototype) function and the cautionary note from MDN: Warning: Modifying an object's [[Prototype]] is currently a slow operation in all browsers due to how modern JavaScript engines ...

How can I access and modify a sub collection document in Angular Firestore?

I am facing a challenge in fetching a single document from a Firestore sub collection with the path: database/users/uid/animal/docID Although I have successfully parsed the docID from another component, I am struggling to retrieve the information to displ ...

Displaying notification in Ionic 2

Whenever I click on the register button, if I fill out all the fields I am taken to the regsuccess page. Otherwise, I receive a message saying to fill in all required fields. However, I want to display an alert message using Ionic2 and TypeScript. HTML: ...

Utilizing the spread operator in Typescript to combine multiple Maps into a fresh Map leads to an instance of a clear Object

Check out the code below: let m1 = new Map<string, PolicyDocument>([ [ "key1", new PolicyDocument({ statements: [ new PolicyStatement({ actions: [&q ...