Observing an observable in RXJS when dealing with a potentially undefined object

I'm trying to figure out how to combineLatest of two sources, one of which may be undefined. Here's what I have:

const observable1 = interval(100);
const observable2 = this.ref?.observable; // a reference that may not exist until the future

combineLatest([observable1, observable2]).subscribe(...)

The issue is I want the output observable to subscribe to this.ref.observable as soon as this.ref is defined (but I can't predict when that will happen).

This is what I've attempted...

observable1.pipe(
   startWith(of(true)),
   switchMap((_) => interval(10)),
   skipWhile((_) => !this.ref),
   switchMap((_) => observable1),
   combineLatestWith(this.ref?.observable ?? EMPTY),
)
.subscribe((val1, val2]) => {...})

However, I encountered TypeScript errors regarding the types returned from combineLatestWith and it feels like an overly complex solution for a seemingly simple problem!

I'm wondering if there's a simpler approach to receiving emissions from a source observable when the object the source observable relies on might be undefined at the time I aim to start observing?

Answer №1

Start by initializing a BehaviorSubject with a value of null.

mySubject: BehaviorSubject<any> = new BehaviorSubject<any>(null);

Next, in the component's ngOnInit or constructor, subscribe to changes in the BehaviorSubject.

ngOnInit() {
    this.mySubject.pipe(
       startWith(of(true)),
       switchMap((_) => interval(10)),
       skipWhile((_) => !this.ref),
       switchMap((_) => observable1),
       combineLatestWith(this.ref?.observable ?? EMPTY),
    )
    .subscribe((val1, val2]) => {...})
}

The view child typically becomes visible during ngAfterViewInit.

ngAfterViewInit() {
    if (this.viewChild?.nativeElement) {
        this.mySubject.next(this.viewChild.nativeElement);
    }
}

Answer №2

Here is the Solution to Address Your Issue

import { CommonModule } from '@angular/common';
import {
  AfterViewInit,
  Component,
  OnDestroy,
  OnInit,
  QueryList,
  ViewChildren,
} from '@angular/core';
import { Subject, combineLatest, interval, takeUntil } from 'rxjs';
import { Site3Child1Component } from './site-3-child-1/site-3-child-1.component';

@Component({
  selector: 'app-site-3',
  standalone: true,
  template: `
   <p>site-3 works!</p>
   <ng-container *ngIf="showChild1">
     <app-site-3-child-1 #child1 />
   </ng-container>`,
  styleUrl: './site-3.component.css',
  imports: [Site3Child1Component, CommonModule],
})
export class Site3Component implements OnInit, AfterViewInit, OnDestroy {
  @ViewChildren('child1') children?: QueryList<Site3Child1Component>;

  protected showChild1 = false;

  private observable1 = interval(1000);

  private destroy$ = new Subject();

  ngOnInit(): void {
    setTimeout(() => {
      this.showChild1 = true;
    }, 2000);
  }

  ngAfterViewInit(): void {
    this.children?.changes
      .pipe(takeUntil(this.destroy$))
      .subscribe((children: QueryList<Site3Child1Component>) => {
        const child1 = children.first;
        if (child1) {
          console.log('child1 is now accessible');
          combineLatest([this.observable1, child1.observable])
            .pipe(takeUntil(this.destroy$))
            .subscribe(([observable1, child1Value]) => {
              console.log(observable1, child1Value);
            });
        }
      });
  }

  ngOnDestroy(): void {
    this.destroy$.next(true);
  }
}

//child

import { Component } from '@angular/core';
import { interval } from 'rxjs';

@Component({
  selector: 'app-site-3-child-1',
  standalone: true,
  imports: [],
  templateUrl: './site-3-child-1.component.html',
  styleUrl: './site-3-child-1.component.css',
})
export class Site3Child1Component {
  public observable = interval(3000);
}

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

Retrieving HTML content from Wikipedia's API using JavaScript

I am encountering an issue where every time I attempt to log data to my console, an error occurs. Could someone kindly point out what may be the problem with the code? My objective is to actually showcase the html content on a webpage. Below is the code ...

The issue with Angular is that it fails to render the object contained within an

Utilizing Angular to retrieve data from an API, the data structure consists of array(object).array(object) This is the data I have https://i.sstatic.net/130z5.png And here is the component TypeScript export class LoginComponent implements OnInit { ...

Insert a fresh row into the gridview using JavaScript

I am working with a grid view where I dynamically add new rows using JavaScript. Each row in the grid view contains an image (addButton), which triggers a specific JavaScript function when clicked. function AddNewRecord(e) { debugger; var hfFirst ...

What is the best way to ensure the secure signing of a transaction in my Solana decentralized application (

I am currently involved in an NFT project that recently experienced a security breach, and I am developing a dapp to rectify the situation. Our plan is to eliminate all NFTs from the compromised collection and issue a new set of NFTs using our updated auth ...

Display the component only if the image source is legitimate

Before rendering an Image component, I want to ensure that the URL is valid and not broken. My current approach seems error-free and the onload function is functioning properly. However, I suspect there might be an issue with how I am handling the return ...

Having trouble converting customized tabs into Bootstrap navigation tabs?

Creating custom tabs with unique tab logic <!-- <lntds-tabs [selectedIndex]="selectedTabIndex" (selectedTabChange)="tabChanged($event)"> --> <!-- <lntds-tab class="custom-tab-group lntdstabsco ...

Enabling communication between App.js and a separate class in React

How can I integrate React Scheduler with JSON data in my app and pass shifts and functions from App.js to DataSheet.js for updating the data? Is there a more efficient way to enable database updates directly from DataSheet? App.js: import React from &apos ...

Unable to include a class when the Hover feature is active

My Current Challenge I've created a list (ul#portfoliolist) with each item serving as a unique navigation element. Upon hovering over any item, the opacity shifts from 0.65 to 1, and the right padding changes from 0 to 10px. Upon moving the mouse aw ...

An issue occurred when trying to trigger a click event within a Blazor WebAssembly

While my dropdown menu option was working fine on a tablet-sized display, it suddenly stopped functioning after I published my project and ran the code in Visual Studio 2019 Preview version 16.10. I'm now seeing an error message in the browser console ...

Determine the value of an array element based on a specified

I am in the process of creating an array, currently consisting of a single object that is computed based on other objects from a JSON file. Sampling my code // Retrieve JSON data and convert it to an object let myFile = '{"foo": {"bar": "baz"}, "thu ...

What steps are needed to enable autocomplete for input fields in React Native Elements on iOS?

I'm currently working on fine-tuning the autocomplete suggestions for my registration form. Within the react native elements input, I've already implemented fields for username, email, and password. Specifically for the email field, I have config ...

Unable to inject a service into an Angular unit test

I am currently working on unit testing an Angular service with the following tools: angular 1.3.8 angular-mocks 1.3.8 karma 0.13.19 jasmine 2.4.1 node 0.10.33 OS: Windows 7 Browser: PhantomJS 2.1.3 However, I am encountering an issue where the Angular s ...

The integration of Meteor.js with an external Mongo database is causing issues with logging in to Mongo

In my project, I am using a meteor.js application along with mongo db (2.6). To create a user in mongo, I followed these steps: use meteor db.createUser( { user: "meteor", pwd: "password", roles: [ { role: "userAdmin", ...

Error: The index $_GET[...] is not defined

When transferring a javascript variable to a php file, I encounter an issue where $_GET['something'] keeps returning as an undefined index. Despite this error, the correct result is displayed and written into the xml. However, when I attempt to ...

How to Retrieve the Current div's ID in VueJS

When using the v-for directive to dynamically generate an id for my div, I need to pass this unique id to a specific function. <div v-for="(item, index) in items" :key="index" :id="'form' + index" > ...

Adjusting the background color of the list item

I'm looking for a way to change the background color of the li tag when the user focuses on the input, similar to what can be seen at the bottom of this page here. After researching similar questions, it appears that achieving this effect in pure CSS ...

Can you provide guidance on utilizing OneNote JavaScript APIs to interpret indented paragraphs within OneNote?

I keep a notebook that contains the following entries: https://i.stack.imgur.com/MLdO0.png For information on OneNote APIs, you can refer to this link (paragraph class selected already) https://learn.microsoft.com/en-us/javascript/api/onenote/onenote.p ...

Obtain the current status of a Stripe charge made with a specific source token using Node.js and

Imagine this scenario: a user submits a credit card token to my server for a purchase, and I save the token in their cart. However, just as I am about to store the charge id from the success response, my server crashes. The charge has been processed, but ...

Switch up your Vue filters with ease

I'm struggling to create filters in Vue that work with arrays of colors and objects called products. I also have a property called count to keep track of clicks: data() { return { count: 0, colors: [ 'red', ...

Looking for guidance on how to deploy a Node server with TypeScript on Vercel

I keep encountering a Code: NOT_FOUND error on my server while running the endpoint. The issue seems to be related to the configuration setup of my TypeScript-based Node server, and I've been struggling with it for quite some time now. Additionally, ...