Rx.js struggles to access historical values

Seeking assistance with retrieving the last 3 values emitted. Despite using the provided code to populate uiOrder and invoking cancelOrderItem() multiple times, I am unable to access the last 3 revisions of the order via getHistory(). Instead, I receive the current value three times consecutively. Even attempting replaySubject(3) yields the same outcome.


export class OrdersService {

    public readonly orders: Observable<Order[]>;
    public readonly uiOrder: Observable<Order>;

    private _orders: BehaviorSubject<Order[]>;
    private _uiOrder: BehaviorSubject<Order>;

    private dataStore: {
        uiOrder: Order,
        orders: Order[]
    };

    constructor() {
        this.dataStore = {
            uiOrder: null,
            orders: []
        };
    
        this._orders = <BehaviorSubject<Order[]>>new BehaviorSubject([]);
        this._uiOrder = <BehaviorSubject<Order>>new BehaviorSubject({});
        this.orders = this._orders.asObservable();
        this.uiOrder = this._uiOrder.asObservable();
    }
    
    getOrder(orderId: number | string) {
        for (let i = 0; i < this.dataStore.orders.length; i++) {
            if (this.dataStore.orders[i].id == orderId) {
                this.dataStore.orders[i].lastAccess = moment().format().slice(0, 19) + 'Z';
                this.dataStore.uiOrder = this.dataStore.orders[i];
                this.updateUiOrder();
            }
        }
    }

    cancelOrderItem(action) {
        this.dataStore.uiOrder.sections[action.sectionIndex].orderDetails.splice(action.orderDetailsIndex, 1);
        this.updateUiOrder()
    }

    getHistory() {
        this.uiOrder.take(3).subscribe((res) => {
            console.log('uiOrder', res);
        }).unsubscribe()
    }

    updateUiOrder() {
        console.log('updating ui order');
        this._uiOrder.next(this.dataStore.uiOrder);
    }

}

What could be causing this issue?

Answer №1

If you are searching for the specific operator, it is bufferCount(3,1). This operator creates a sliding window of the last 3 values emitted. The only downside is that it will start emitting only after accumulating 3 values. To include the first value as well, you can use the following approach:

Rx.Observable.from([null,null])
  .concat(this.uiOrder)
  .bufferCount(3,1)
  .subscribe(uiOrderHistory => ... );

This arrangement will result in a marble diagram like this:

---Order1-----------------Order2--------------------Order3
bufferCount(3,1)
---[null,null,Order1]-----[null,Order1,Order2]------[Order1,Order2,Order3]

Answer №2

Perhaps you are overanalyzing the situation. Instead of constantly searching for the latest 3 orders, consider storing them in an array that is updated every time a new order is emitted by uiOrder.

orderList: Order[] = [];

orders$ = this.uiOrder.subscribe(order =>
   let history = this.orderList;
   //add new order to history array:
   history = [...history, order];
   //keep only the last 3 orders in the array:
   if (history.length > 3) history.splice(0, history.length - 3)
);

Now, whenever you need to access the most recent 3 orders, simply refer to the orderList. This approach also ensures synchronous operation.

Answer №3

fetchRecentData() {
this.latestData.takeLast(3).subscribe((data) => {
  console.log('Latest data', data);
}).unsubscribe()
}

takeLast  method fetches the most recent three data points from the latest dataset.

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

How can we assign various class names depending on the value of an object?

I have a set of objects stored in my component. I need to dynamically apply different classes based on the value of the ErrorLevel property within each object. If an object has ErrorLevel equal to 1, I want to assign the following classes to various elemen ...

A data type representing a specific category rather than a specific object

My job involves working with Sequalize models, which are essentially classes. Upon registration, these models are populated with some data that needs to be stored. To accomplish this, I store them in a list. However, when retrieving a model into a variab ...

Error Message: Angular 5 - Unable to bind to 'ngModel' as it is not recognized as a valid property of 'input'

I am currently working on an Angular 5 online tutorial using Visual Studio Code and have the following versions: Angular CLI: 7.0.6 Node: 10.7.0 Angular: 7.0.4, Despite not encountering any errors in Visual Studio Code, I am receiving an error in ...

Error in angular2-color-picker module: Unable to retrieve the property 'substr' from an undefined source-node in source-node.js

Error in angular2-color-picker: Issue with 'substr' property, source-node.js This error occurred when I executed: npm i --save angular2-color-picker Any suggestions on how to fix this problem? ...

Having issues getting Angular up and running

I'm having some issues with the global installation of Angular. Below is the error message I received: C:\Users\DevSa\ng -> C:\Users\DevSa\node_modules\@angular\cli\bin\ng > @angular/<a href ...

Exploring Angular 2/4: Unpacking the Process of Accessing API Data Using Tokens

Hello there, I am trying to retrieve API data with a token using Angular 2/4. Below is the code I have written: import { Component, ViewEncapsulation } from '@angular/core'; import { Http, Response } from '@angular/http'; import &apos ...

How to extract the chosen option from a bound list within an Angular application

Our goal is to avoid using 2-way binding in our component setup: <select type="text" formControlName="region" (change)="regionChanged($event)"> <option *ngFor="let region of regionsDDL" [ngValue]="region">{{region.name}}</option> ...

Extract a string value from a TypeScript enum

Here is a basic enum definition: export enum Type { TEST_ONE = "testing.one", TEST_TWO = "testing.two", BETA = "beta.one" } I am looking to run a function for each string value in the enum. For example: executeType(type: string) { console.lo ...

Using Angular 4 to populate a form and ensure it remains untouched

Designed an update form that is pre-populated with information. I am aiming for the button to be inactive until any changes are made within the form The form group utilizes valueChanges to detect when information has been modified However, even when I u ...

Custom "set attribute" feature in TypeScript

One issue I faced was resolved by creating the function shown below : function setProperty<T extends Record<string, string>>(obj: T, key: keyof T) { obj[key] = "hello"; } However, when I tried to compile the code, I encountered an ...

Achieving the highest ranking for Kendo chart series item labels

Currently, I am working with a Kendo column chart that has multiple series per category. My goal is to position Kendo chart series item labels on top regardless of their value. By default, these labels are placed at the end of each chart item, appearing o ...

Using Typescript for Asynchronous Https Requests

I've been attempting all day to make an https request work. My current code isn't functioning as expected; when I run it, I encounter an "Unhandled error RangeError: Maximum call stack size exceeded at Function.entries" import * as https from &q ...

Can icons with an external path be utilized as a src in the manifest.json file within an Angular application?

Let's visualize the setup with two projects - project1 and project2. Each project has its own manifest.json file and the same apple-touch-icon-144x144.png file located in assets/icons directory. -project2 |_src | |_assets | | |_icons | | ...

Disregard earlier callback outcome if there has been a change in the state since then

I am facing an issue with my page that displays a list of countries retrieved from an external library. When I click on a country, it should show me all the cities in that specific country. Each country object has a provided method to fetch the list of c ...

Angular Dependency Injection: Individual instances of each service are provided for every module usage

Within my application, there is a module called "FileUpload". The upload service included is "UploadService", which receives a service injection with the interface "RequestService." I also have two other modules: FileManager1 and FileManager2. Each file m ...

Creating Angular unit test modules

When it comes to creating unit test cases for an Angular app, the application functionality is typically divided into modules based on the requirements. In order to avoid the need for repeated imports in component files, the necessary components, modules, ...

"Creating a backend server using Node.js, TypeScript, and g

I am currently in the process of developing a nodejs project that will consist of 3 key services: Gateway Product Order The Product and Order services will perform functions related to their respective names, while the Gateway service will take JSON requ ...

Saving in prettier differs from running it with npm

./file.ts (INCORRECT) import { jwtGroupClaimToRolesDomain, ScopeIds } from '@invison/shared'; import { Injectable, NestMiddleware } from '@nestjs/common'; import { ConfigService } from '@nestjs/config'; import { Response } fro ...

Steps to Turn Off Angular 2 Material Input Field

Please carefully review the Description below before proceeding: This is an HTML file containing code snippets: <div class="row col-md-2"> <mat-form-field appearance="outline" class="nameInput col-md-2"> <mat-label>One< ...

Unexpected behavior: Angular post request does not include the expected request body

Embarking on my initial solo Angular project... I am endeavoring to make a post request to my freshly created web service and have implemented the following code: headers = new HttpHeaders( {'Content-Type':'text/plain'} ); l ...