The RxJS Observable using Subject, timer polling, and combineLatest fails to trigger

I developed a function to conduct polling on an API while incorporating pagination. For this purpose, I utilized a Subject Observable for pagination and implemented polling using the timer method (I attempted interval as well with similar outcomes).

Below is the code snippet:

  getItems(pagination: Subject<Pagination>): Observable<ListResult<Item>> {
    let params: URLSearchParams = new URLSearchParams();

    return Observable
      .timer(0, 5000)
      .combineLatest(
        pagination,
        (timer, pagination) => pagination
      )
      .startWith({offset: 0, limit: 3})
      .switchMap(pagination => {
        params.set('skip', pagination.offset.toString());
        params.set('limit', pagination.limit.toString());
        return this.authHttp.get(`${environment.apiBase}/items`, {search: params})
      })
      .map(response => response.json() as ListResult<Item>)
      .catch(this.handleError);
  }

The intended functionality is as follows: An HTTP request will be triggered every 5 seconds AND when there is a change in page by the user.

This is what occurs: Initially, the first HTTP request is made, but subsequent requests are not sent to the server UNTIL pagination is applied. Once pagination is used for the first time, the polling mechanism starts functioning properly.

Due to being new to Observables, I might have overlooked something crucial despite my best efforts to identify any missed elements.

I also experimented with an alternative approach (perhaps lacking the timer counter in startWith), yet it did not yield any changes in behavior.

[...]
  .combineLatest(
    pagination
  )
  .startWith([0, {offset: 0, limit: 3}])
[...]

Answer №1

When using the combineLatest() operator, it's essential for all source Observables to emit at least one item.

In your example, only one request is made due to the use of .startWith(). Since the combineLatest() never emits, it suggests that the pagination being a Subject, may not be emitting any items.

An alternative approach could be moving the .startWith() like this:

.combineLatest(
  pagination.startWith({offset: 0, limit: 3}),
  (timer, pagination) => pagination
)

If you're mainly interested in items from pagination and not timer(), you might consider using merge() to refresh the list from either source. This way, timer() can independently increase the offset.

Observable
  .timer(0, 1000)
  .map(i => { return {offset: i*3, limit: 3}})
  .merge(pagination.startWith({offset: 0, limit: 3}))
  .switchMap(pagination => {
    return Observable.of(pagination).delay(200)
  })
  .subscribe(val => console.log(val));

Answer №2

Ensure that you follow the steps outlined below

Generating Observable Data

To generate observable data, create an Observable variable and push data using observable.next(value);

Adding Data to a Subject or Behavior Subject

To access the data where needed, declare a variable of type Subject and subscribe to it.

private val: Subject = YourObservable;
private uiValue: string;

val.subscribe((val) => {
   uiVal = val;
});

Now you can utilize the uiVal anywhere, which will refresh at set intervals.

You can independently test both components by using console.log to ensure smooth operation.

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

Removing buttons from a table row dynamically

Below is how I am adding the Button to Element: (this.sample as any).element.addEventListener("mouseover", function (e) { if ((e.target as HTMLElement).classList.contains("e-rowcell")) { let ele: Element = e.target as Element; let ro ...

ACE editor error: Attempted to access the 'getValue' property of an undefined object

In the process of developing an Angular markdown editor, I have integrated the ACE editor as a code editor. The npm package for ACE editor can be found here. You can access a codesandbox version of the project here. My current challenge involves retrievi ...

Angular: Dynamically changing checkbox's status from parent

I'm in the process of developing a switcher component that can be reused. The key requirement is that the state of the switch should only change after an API call is made at the parent component level. If the API call is successful, then the state cha ...

Complete the required field in the update section of an Angular/Firestore CRUD operation

I'm struggling to find a simple solution for displaying the current field entry in a form based on the id sent in the url within Firestore. The 'where' condition doesn't seem to be working properly either. When attempting to edit an en ...

Encountered an issue with valid types while executing the following build

Encountering an error when attempting to run the next build process. https://i.stack.imgur.com/qM3Nm.png Tried various solutions including updating to ES6, switching the module to commonJs, downgrading webpack to version 4 with no success. The only worka ...

Transitioning to @angular/router version 3.0.0-alpha.3: A guide to implementing OnActivate upgrade

Recently, I updated @angular/router to version 3.0.0-alpha.3 and noticed that the OnActivate interface, which was present in version 2.0.0-rc.1, seems to be missing. Any clues on this change would be greatly appreciated. ...

React Error: Unable to access property 'getBoundingClientRect' because it is undefined

server: Node.js, MongoDB, Graphql front-end: React --typescript, apollo-client, Graphql I believe the issue lies in the timing or sequencing of data retrieval and rendering. However, I'm struggling to find a solution to this problem. Error Uncaug ...

What is the best way to incorporate the trix-editor into an Angular 2 application?

I've been struggling to incorporate the Trix editor into my Angular application. I can't seem to find any resources or npm packages that explain how to install the Trix editor in an Angular 2 app. Can anyone provide guidance on where to find the ...

Creating a conditional interface based on props in TypeScript: A step-by-step guide

What is the most effective way to implement conditional props in a component that can be either a view or a button based on certain props? Let's take a look at an example called CountdownButtonI: class CountDownButton extends Component<CountdownBut ...

What is the best way to include a PHP mail file in an Angular project?

I have recently developed a single-page application using Angular that features a contact form. To handle the functionality of this contact form, I opted to use the PHP mail function. The PHP file responsible for handling the form submissions is located wi ...

Angular 13 - Encountering issue with "Cannot access properties of null (reading 'getParsed')"

Currently working on a new Angular 13 project and running into an error: TypeError: Unable to access properties of null (reading 'getParsed') at .../main.2506c840be361c93.js:1:325924 at Array.filter () at nd._getActiveElements (.../main.2506c84 ...

What is the best way to incorporate a .json configuration into the environment.ts file and access an API with Angular

I need to import a Json file from the assets folder containing URLs like the following: config.json: { "url1": "https://jsonplaceholder.typicode.com/posts", "url2" : "https://reqres.in/api/users", ...

Experimenting with Cesium using Jasmine (Angular TypeScript)

I have a TypeScript app built using Angular that incorporates Cesium: cesium-container.component.ts import { Component, ElementRef } from '@angular/core'; import { Viewer } from 'cesium'; import { SomeOtherCesiumService } from 'sr ...

What is the process for linking a Python Flask CAS server with an Angular application?

After successfully setting up the python server (Flask to be specific) and establishing a successful connection to my CAS server, it is working flawlessly by redirecting to CAS login and returning accurate user data upon login. Here is the relevant code sn ...

When the component I created for dark mode is clicked, the colors in react-tsparticles change dynamically

I am looking to modify the theme of the react-tsparticle component function Particle() { const particlesInit = (main) => {}; const particlesLoaded = (container) => { <DarkMode />; container.loadTheme("dark&q ...

Combining data types to create a unified set of keys found within a complex nested structure

This problem is really testing my patience. No matter what I do, I just can't seem to make it work properly. Here's the closest I've come so far: // Defining a complex type type O = Record<'a', Record<'b' | 'x& ...

Displaying data retrieved from Angular by clicking a dropdown button

Struggling with a minor issue while using Angular on the frontend and .NET Core on the backend? Look no further, I have created a video demonstration below to help you out. Despite spending countless hours trying to solve the problem, it still persists. T ...

Utilizing Shadow Root and Native Web Components for Seamless In-Page Linking

An illustration of this issue is the <foot-note> custom web component that was developed for my new website, fanaro.io. Normally, in-page linking involves assigning an id to a specific element and then using an <a> with href="#id_name&quo ...

How can we display the numbers between two given numbers in Ionic 2 while incrementing or decrementing the value?

I am developing a geolocation-based speed tracking feature that displays the speed on the screen. However, I have encountered a problem where there is a significant gap between the previous and current speed values, and I would like to implement a transiti ...

TRPC error: The property 'useInfiniteQuery' is not found in the type '{ useQuery'

Issue with TRPC I am facing a problem with my tweetRouter that has a timeline query returning tweets and a NextCursor. However, I encounter an error when trying to access useInfiniteQuery in my components. ** Property 'useInfiniteQuery' does no ...