RxJs: The art of updating a BehaviorSubject by concatenating the latest value with a new one

Within my Angular application, I am currently implementing a state management system using BehaviourSubject

This is what I have in my store file:

myStoreData = new BehaviourSubject([])

In my actions file, I have the following:

export const SAVE_DATA_IN_CONTEXT = '[User] Save user the incoming data';

Therefore, in the component, when necessary, the method to invoke is as follows:

click(newData){
  this.reducerService('SAVE_DATA_IN_CONTEXT' , newData)
}

My goal is to ensure that the data sent to the store (BehaviourSubject) does not replace the existing data but appends it to it:

The desired outcome should be:

Data to send to BehaviourSubject (array) = existing data (array of objects) + new data (object)

This is how my reducer looks, and here is what I have tried:

public dispatchAction(actionTag: string, newDataPayload: any | null): void {
    
    switch (actionTag) {
      case ActionsTags.SAVE_DATA_IN_CONTEXT :
        const newDataToSet = [...Stores.myStoreData.getValue() , ...newDataPayload ];
        Stores.myStoreData.next(newDataPayload);
        break;

}

I believe that using the getValue() method is not ideal, and I want to avoid using Stores.myStoreData.subscribe() due to potential unsubscription issues and repetitive subscriptions from the user click method.

I am seeking a better way to handle this process effectively, such as potentially changing the BehaviourSubject implementation.

Any suggestions?

Answer №1

In response to the comments on your query, it is noted that specialized libraries exist for this task, which would be more efficient than starting from scratch.

However, if you are looking to gain insight through hands-on experience, let's proceed with developing the solution ourselves.

My suggestion would be to adopt a reactive programming approach and structure everything as streams. Create a minimal service layer for better organization and ease of use via dependency injection.

To implement reactivity, I would utilize a subject to handle actions. Subsequently, maintain the state within a stream using the following methodology:

const action$ = new Subject();

const state$ = action$.pipe(
  scan((state, action) => {
    switch (action.type) {
      case 'some_action':
        // todo: generate a new state
      default:
        state;
    }
  })
);

If you wish to encapsulate this functionality into a service, it can be achieved with the following code snippet:

@Injectable()
export class Store {
  private action$ = new Subject();

  public state$ = action$.pipe(
    scan((state, action) => {
      switch (action.type) {
        case 'some_action':
          // todo: generate a new state
        default:
          state;
      }
    }),
    shareReplay(1)
  );

  public dispatch(action): void {
    this.action$.next(action)
  }
}

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

Issue with displaying Bootstrap modal on top of another modal

Upon clicking the "Click me here" button, a modal pops up and displays a toast message expressing gratitude. The thank you modal should remain open on top of the save modal even after clicking save. However, upon saving, an error message appears: Cannot r ...

I attempted to invoke a JavaScript function upon clicking an ASP button via the code behind, but unfortunately, it did not function as intended

My .aspx page contains a JavaScript function <script type="text/javascript"> function openCity(evt, cityName) { var i, tabcontent, tablinks; tabcontent = document.getElementsByClassName("tabcontent"); for (i = 0; i < tabcontent.length ...

Modifying the color of a non-active tab - Material UI Tabs

Is there a way to customize the color of inactive tabs in Material UI tabs? I have noticed that they currently appear black, as shown in the screenshot here: screenshot Thank you! ...

Error message: "wp is not defined" appears when using TinyMCE, Bootstrap Modal, and URL Parameter together

Currently utilizing Bootstrap 5 alongside WordPress 6.2 In the process of developing a WordPress plugin, where I have successfully created a Dashboard and an All Content page. On the Dashboard page, users can find a list of the most recently created cont ...

Discovering the total number of pages in a PDF generated using Puppeteer

I am currently in the process of determining the page count for a single PDF file / what is the total size of the PDF file created by puppeteer.page according to my needs This is the approach I have taken: try { const generatedPdfFilePath = `${ ...

The property 'enabled' is not a standard feature of the 'Node' type

Within the code snippet below, we have a definition for a type called Node: export type Node<T> = T extends ITreeNode ? T : never; export interface ITreeNode extends TreeNodeBase<ITreeNode> { enabled: boolean; } export abstract class Tre ...

Angular 9 Alert : TypeError: Unable to access property 'routes' as it is undefined

Currently, I am in the process of learning Angular 9 and experimenting with new features. Recently, I decided to explore router-outlets with a name property which is demonstrated in the code snippet below. This is the template I used: <router-outlet n ...

` `endless scrolling within reactjs` `

function InfiScroll ({items}) { items.filter(newItem => !existingItems.some(existingItem => existingItem.key === newItem.key)).map(newItem => <Item item={newItem} key={newItem.key}></Item>) } I am working with a component ...

Jquery Deferred failing to activate done or when functions

I'm currently working with 2 ajax calls that I'm connecting using $.when in order to execute certain tasks once they are completed. Below is the code snippet: function ajaxCall(url, targetDiv) { dfd = new $.Deferred(); $.ajax({ ...

Determine the presence of a particular set of values within an array of named objects stored in the browser's localStorage using JavaScript

Previously, I stored various objects in localStorage in the following format: console.log(localStorage) // The storage output may vary, with different objects (such as randid) Storage { 876346545: "{"ABA":"876346545","A ...

Unique Timer with progress bar that resets only when the page is refreshed

We're currently developing a screening tool with a section for questions. Beneath each question, there is a progress bar displaying the time remaining. However, the progress bar only updates when the page is reloaded. Here is the code snippet: publi ...

Incorporating ng2-bootstrap into an Angular2 project with SystemJS starter template

I am attempting to integrate the ng2-bootstrap modal functionality into a component of my project that is built using the angular2-starter. Below is my systemjs.conf.js configuration: /* * This config is only used during development and build phase onl ...

The module could not be located: Issue: Unable to find 'vue-confirm-dialog'

My app is built on Vue.js + node.js. I recently tried to integrate the vue-confirm-dialog package from npm, but encountered an issue with this code line: import VueConfirmDialog from 'vue-confirm-dialog' Despite running npm install --save vue-co ...

How can you modify the color of a card in React by mapping through an array and evaluating its value?

I'm attempting to modify the color of a card depending on the current slot value, which is an object in an array. While I am iterating through each card, I want to adjust the background color of the card based on this value. However, my current method ...

Integrate a fresh component and include a hyperlink to the URL simultaneously

Seeking to create a system where clicking an item in the navbar loads a new component on the screen, I am faced with the challenge of maintaining state while also updating the URL. Allow me to provide more details: Below is my current navbar code snippet: ...

What is the process for creating a login page that redirects automatically?

For instance: Whenever I enter gmail.com, it automatically takes me to this link: https://accounts.google.com/signin/v2/identifier?service=mail&passive=true&rm=false&continue=https%3A%2F%2Fmail.google.com%2Fmail%2F&ss=1&scc=1&ltmp ...

Experience the auditory bliss with Javascript/Jquery Sound Play

I am creating an Ajax-driven application specifically for our local intranet network. After each response from my Ajax requests, I need to trigger a sound in the client's browser. I plan to store a sound file (mp3/wav) on our web server (Tomcat) for ...

A versatile Material UI paper that adjusts its dimensions dynamically

Utilizing Material-UI's Paper component (https://mui.com/components/paper/), I've encountered a scenario where the content within the Paper element needs to be dynamic. <Paper className="modal" elevation={3}> ...Content </Paper ...

Implement the maskmoney library in your input fields

In the form below, I am automatically adding inputs using a JavaScript function like this: $('.Preco1').maskMoney({ decimal: '.', thousands: ' ', precision: 2 }); $('.Preco1').focus(); $('#sub').maskMon ...

Applying a transparent layer to all slider images, with the exception of the one that is

I am utilizing an IosSlider that is functioning properly, but I am looking to enhance it by adding opacity to all images except for the selected image. This adjustment will make the selected image stand out more and enable users to focus on one image at a ...