combineLatest operates independently of an observable's emission timing

I am facing an issue with two services in my application. Each service has an observable, and I have a component that is supposed to get the last emitted value of both observables. However, I noticed that the combineLatest function fires as soon as one observable changes, instead of waiting for both:

export class CreateSessionComponent {
  constructor(
    private sessionService: SessionService,
    private userService: UserService
  ) {
    combineLatest([this.userService.user$, this.sessionService.session$])
      .subscribe({
        next: (data) => console.log(data),
      });
  }

  public createUserAndSession(): void {
    this.sessionService.createSession();
    this.userService.createUser();
  }
}
export class UserService {
  private userSubject = new BehaviorSubject<any | null>(null);
  public user$ = this.userSubject.asObservable();

  public createUser(): void {
    setTimeout(() => {
      this.userSubject.next(`User ${Math.random()} `);
    }, 5000);
  }
}
export class SessionService {
  private sessionSubject = new BehaviorSubject<any | null>(null);
  public session$ = this.sessionSubject.asObservable();

  public createSession(): void {
    setTimeout(() => {
      this.sessionSubject.next(`Session ${Math.random()} `);
    }, 2500);
  }
}

Upon calling the function, I receive values in the combineLatest() at 2500ms and 5000ms.

https://stackblitz.com/edit/angular7-rxjs-g435xp

Answer №1

combineLatest follows the rule:

Whenever any observable emits a value, emit the most recently emitted value from each.

If you wish to wait for both observables to emit their values before proceeding, consider using zip in place of combineLatest. Below is an updated version of your create-session.component.ts:

import { Component } from '@angular/core';
import { zip } from 'rxjs';
import { SessionService } from '../session.service';
import { UserService } from '../user/user.service';

@Component({
  selector: 'app-create-session',
  templateUrl: './create-session.component.html',
  styleUrls: ['./create-session.component.css'],
})
export class CreateSessionComponent {
  constructor(
    private sessionService: SessionService,
    private userService: UserService
  ) {
    zip(this.userService.user$, this.sessionService.session$)
      .subscribe({
        next: (data) => console.log(data),
      });
  }

  public createUserAndSession(): void {
    this.sessionService.createSession();
    this.userService.createUser();
  }
}

Answer №2

Ensure the emitted values are not null by filtering out any observables that have a value

combineLatest([this.userService.user$, this.sessionService.session$]).pipe(
  filter(([user, session]) => user !== null && session !== null)
)

To prevent emission when either is null, reset them to null in createUser and createSession before triggering the observable.

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

Creating a relationship of dependence between functions in TypeScript: A guide

Apologies for the unclear title, I'm struggling to articulate my question effectively. Currently, I am attempting to create a method that can parse an object from an XML file. The XML structure (translated to JavaScript using xml-js) appears as follow ...

Angular lazy loading routes do not function as intended

I currently have a project that is divided into different modules. Among these modules, the ones that are lazy loaded include the about and contact modules. The navigation menu containing the router links is located in a feature module alongside the header ...

Unable to execute the "install code command in PATH" command

I am encountering an issue with Visual Studio Code where the "install code command in path" option does not show up when I try to access it using Shift + Ctrl + P. My operating system is Windows 10 and I am running the latest version of Visual Studio Code. ...

Getting a JSON value and saving it to a variable in Angular 4

Here is the JSON structure: { "Semester": [ { "queueName": "Science", "totalCount": 300, "unassignedCount": 10, "subjectDetails": [ { "subjectName": "Chemistry", "sectionOne": 100, "secti ...

How to include subdirectories in a TypeScript npm module

I am in the process of developing a package for npm and I would like it to be imported in the following manner: import myPackage from 'my-package'; import { subFunction1, subFunction2 } from 'my-package/subfunctions'; Upon trying to u ...

Prevent tooltip text from appearing when a button is disabled in an angular application

As a beginner in UI development, I have a requirement for my Angular application. I need to enable and disable a button based on certain conditions. The tricky part is that I want to display a tooltip only when the button is enabled. I have managed to chan ...

"Develop a unique Angular 12 custom pipe that retrieves data through a service and converts it into a string instead of

Hello Everyone, I've encountered a problem that I need help with. import { Pipe, PipeTransform } from '@angular/core'; import { PrintingTypesService } from 'src/app/settings/services/printing-types/printing-types.service'; import { ...

Setting up subscriptions within a dynamic array: A step-by-step guide

I am currently in the process of learning Angular and trying to understand RxJS, Observable, etc. I seem to be struggling with syntax and concepts at this stage. My goal is to create a service called incidentService that retrieves an array of incidents an ...

Display content based on selected option

I am struggling to display a div based on the selection I make. Unfortunately, it's not working as expected. Can anyone offer guidance on how to tackle this issue? <div class ="row"> <div class="form-group col-md-6"> <label for= ...

Upon updating the file extension from js to ts, Ionic is no longer able to locate the module

I have been using the Ionic framework to develop a mobile application by following the guidance provided at http://ionicframework.com/docs/v2/getting-started/tutorial/. ionic start my-mobileapp sidemenu --v2 After that, I launched the app in a browser us ...

Verifying if an object in TypeScript contains a property with a value of true

I need to verify if the object below contains the property forums and if its value is set to true. {forums: true, pages: true, photos: true, videos: true} Currently, I am working with TypeScript Angular 5. The code snippet below accomplishes this task e ...

Unable to compile Webpack due to aws-jwt-verify issue

Trying to package node code for an AWS lambda function with lambda@edge, and running into an error. Module not found: Error: Can't resolve 'aws-jwt-verify/error' Typescript compiles successfully with TSC, but webpack throws this error durin ...

Different Ways to Remove an Element from an Array in TypeScript

I have been browsing through the responses here, but none of them seem to work for me. I am trying to remove an item from an array, but no matter what I do, the index keeps returning as -1. deleteItinerary(id: string) { this.dataSvc.removeItinerar ...

Angular 8 HTTP Interceptor causing issues with subscriptions

I'm currently in the process of setting up an Angular 8 project that will allow me to mock API calls using HTTP INTERCEPTORS. My approach involves adding a --configuration=mock flag to my ng serve script so that the interceptor is injected into my app ...

Is it possible for me to incorporate a new feature into a library that operates using its unique interface?

I'm currently utilizing the angular-gridster2 library and I am looking to add two additional properties in the gridsterItem interface to hold some specific values. How can this be achieved? Despite creating an extended interface of their own, the pack ...

Having trouble troubleshooting React Typescript in Visual Studio Code?

I am currently facing a challenge while debugging a React Typescript application in VS Code. I am struggling to configure the launch.json file in order to enable TSX debugging. For bundling everything into a single JS file, I am utilizing webpack. Below ...

Utilizing Dynamic Variables in Angular Module Declarations

I am facing an issue with importing a module in my @NgModule setup. Currently, I have the following code: MqttModule.forRoot(environment.MQTT_SERVICE_OPTIONS) However, I want to retrieve the value from a configuration file instead of the environment. To ...

Tips on displaying the entire text when hovering over it

I'm facing an issue with a select element that retrieves options from an API. The problem is that some options are too large for the text box and get cut off, making them hard to read for users. <div class="form-group my-4"> <lab ...

When attempting to add mp3 files to a Vue/TypeScript application, a "Module not found" error is triggered

I am encountering an error while trying to import .mp3 files into my Vue/Typescript app. Upon running 'npm serve', I am presented with the following message: ERROR in /Users/***/***/application/src/components/Sampler.vue(80,16): 80:16 Cannot fin ...

Tips on "populating" generic parameter in typescript

Imagine I have a generic TypeScript function that looks like this: function performAction<X>(input: X): X { //... } Now, let's consider a specific interface called YourType: interface YourType { a: string; b: number; } I aim to exp ...