Why do my messages from BehaviorSubject get duplicated every time a new message is received?

Currently, I am using BehaviorSubject to receive data and also utilizing websockets, although the websocket functionality is not relevant at this moment. The main issue I am facing is why I keep receiving duplicated messages from BehaviorSubject.

When examining the code in the service:

hubMessage$ = new BehaviorSubject({});  


public startConnection = (id: number) => { 
    this.hubConnection = new signalR.HubConnectionBuilder()
        .withUrl('https://api/hub')
        .build();


    this.hubConnection
        .start()
        .then(() => { 
            console.log('connection established')
        }
        )
        .catch(err => {
            console.log('Error while starting connection: ' + err)
            this.retryConnection();
        }) 
}

public newLocationRecieved() {
    this.hubConnection.on('NewLoc', (data) => { 
        console.log('new location recieved' , data)
        this.hubMessage$.next(data); 
    })
}

public sendDriverId(id: number = 1) {
    this.hubConnection.send('SubOnDriver', { driverId: id })
}

Every 20 seconds, a new location update is received. I need to prevent previous data from accumulating in hubMessage, as it causes my software to crash after one minute due to duplicate messages.

Imagine if every message you received was duplicated exponentially: one first, then two, then four, then sixty..32....64...

Why is this happening?

How can this issue be resolved?

In the component, I use this message as follows:

Component code:

  ngOnChanges() {
    this.dispatchDetails;
    this.createMarkers();
  }

  createMarkers() {
    console.log('Connection started right now ', this.dispatchDetails) 
    this.newCoordinate(); 
  }


  private newCoordinate = () => { 
      this.signalRService.hubMessage$.subscribe(
        (data: any) => {
          console.log('received new coordinate ?', data); // HERE I AM RECEIVING TOO MANY DUPLICATE MESSAGES
          this.signalRService.newLocationRecieved()
          this.locationCoords = data;
          if (this.locationCoords.location) {
            this.latitude = this.locationCoords?.location?.latitude
            this.longitude = this.locationCoords?.location?.longitude
          }
        }
      )
    }

I may need to clear my variable or perhaps there is an issue with the websocket connection?

Is the websocket connection possibly causing duplicates, which seems unlikely?

You probably understand that creating a minimal reproduction code for web sockets is challenging...

Answer №1

The reason for the duplicated messages is that the createMarkers() function is being called within the ngOnChanges lifecycle hook. This causes the function to be executed repeatedly whenever there is a change in the component-scoped value, leading to multiple subscriptions and duplicated messages. To resolve this issue, you should only call the function once when creating the component or perform necessary checks to prevent creating new subscriptions if existing ones already exist.

Answer №2

You have registered for updates from this.signalRService.hubMessage$. Whenever new data is received from that behavior subject, you trigger

this.signalRService.newLocationReceived()
.

this.signalRService.hubMessage$.subscribe(
    (data: any) => {
      ...
      this.signalRService.newLocationReceived()
    }

This action creates a fresh callback function:

public newLocationReceived() {
    this.hubConnection.on('NewLoc', (data) => { 
        this.hubMessage$.next(data); 
    })
}

resulting in redundant values. To optimize, I recommend moving the callback into the startConnection method.

public startConnection = (id: number) => {
  ...
  this.hubConnection.on('NewLoc', (data) => {
    console.log('new location received', data)
    this.hubMessage$.next(data);
  });
}

Edit:

Additionally, this.createMarkers(); should be relocated from ngOnChanges to ngOnInit. Credit goes to @Liu Zhang

Answer №3

Within the message handler of newCoordinate, you are invoking

this.signalRService.newLocationRecieved()
, leading to the initialization of another event handler that sends another message to the hubMessage$. It would be more efficient to perform this action only once, most likely in the startConnection function.

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

Methods for hiding and showing elements within an ngFor iteration?

I am working on an ngFor loop to display content in a single line, with the option to expand the card when clicked. The goal is to only show the first three items initially and hide the rest until the "show more" button is clicked. let fruits = [apple, o ...

Is there a way to prevent npm from compiling with each keystroke in Visual Studio Code?

Currently, I am enrolled in a training program to enhance my skills in angular/node/npm. However, I have been facing an issue with npm constantly compiling my source code every time I make a keystroke in vs-code. Despite not having Auto-save enabled in v ...

Node.js: Steps for receiving an ArrayBuffer in a $http request

I made a request using $http.post from Angular.js to Node.js, expecting to receive an ArrayBuffer. Here is the code snippet: $http.post('/api/scholarships/load/uploaded-files', Global.user, {responseType:'arraybuffer'}).success(functi ...

Is it possible to retrieve the current CSS value set by a media query using JavaScript?

Currently working on a website project that involves accessing and manipulating the display property of a menu. The goal is to toggle the menu open or closed based on its current state. In my setup, the initial state of the menu is defined as closed using ...

Do you think it's important to include a maxlength validation message for an input field in Angular?

Utilizing the maxlength attribute on a form field not only enables Angular's default validation, it also restricts input beyond the specified length from being typed into the text box. So, does this imply that displaying an error message for violating ...

Tips for producing/reserving cropped images from a photo? (includes converting images to base64 format)

https://i.sstatic.net/6Nath.png Imagine having two square datasets taggedImages: { 0: {id:0, left:100, top:100, thumbSize:100, type: 'A', seasons: ['All', 'All']}, 1: {id:1, left:200, top:200, thumbSize:100, type: &apos ...

Arranging titles on the top of the page in a column format, resembling an index

Has anyone figured out how to make the title of the content stick at the top, one below the other, as the user scrolls? I've been using Bootstrap's Scrollspy, which works fine, but I need a few additional features. You can check out the codepen l ...

What is the method for incorporating a customized button into the header of a Dynamic Dialog using PrimeNG?

I'm currently working on a project using Angular v17 and PrimeNG. I need to add buttons to the header of a dynamic dialog, but I've been struggling to find a solution. Here's the code snippet from my dialog component: show(j): void { ...

Mastering the art of shaping state in NGRX for the master-detail pattern

Imagine a scenario where I am developing a compact app for organizing tasks. This app makes use of angular and NGRX to efficiently manage the state. Each day, the user loads tasks in the morning and then travels to different locations to complete them. Th ...

Unable to retrieve Angular Service variable from Controller

I am facing an issue with my Angular Service. I have set up two controllers and one service. The first controller fetches data through an AJAX call and stores it in the service. Then, the second controller tries to access this data from the service. While ...

Strange behavior is observed when using ng-view inside ng-controller, especially when refreshing the

Here is the code I am working with: <body ng-controller="CoreCtrl"> <div ng-cloak> <!-- NavBar --> <div ng-include="'/app/core/navbar.html'"></div> <!-- Main content --> <div class="con ...

The process of running npx create-react-app with a specific name suddenly halts at a particular stage

Throughout my experience, I have never encountered this particular issue with the reliable old create-react-app However, on this occasion, I decided to use npx create-react-app to initiate a new react app. Below is a screenshot depicting the progress o ...

Error: UserService (?) is missing parameters and cannot be resolved

Upon compiling my application, an error is appearing in the console: Uncaught Error: Can't resolve all parameters for UserService (?) Despite having @Injectable() present for the UserService, I am unsure where to troubleshoot further. import {Inj ...

Requirements for adding information to a database table

I'm new to JavaScript and facing an issue that I need help with. I am trying to insert data into a database table based on certain conditions in my code, but even though I receive an error message when I input incorrect values, the data still gets ins ...

Angular's observables were unable to be subscribed to in either the constructor or ngOnInit() functions

Currently, I am incorporating an observable concept into my application. In this setup, a service is called by component1 to emit an event that is then subscribed to by component 2. Below is the code snippet for reference: Service Code export class Mes ...

Unique Version: Some effective tips for utilizing a fork of type definition such as @types

Currently, I am utilizing Typescript 2.0 along with @types and the experience has been quite positive. Thanks to @types, we can easily leverage type definitions by simply installing the package via npm. Surprisingly, I have not delved into how it actually ...

Create an object that may have any number of keys, but must have at least one key defined

Is there a way to accomplish this task? type Plant = "rose" | 'tulip' | 'daisy' type PlantCollection = { [p in Plant]?: number } const validPlantCollection: PlantCollection = { rose: 1, daisy: 2 } const emptyCollectionShouldBeRejec ...

Do overlay elements have to be positioned at the bottom of the HTML body every time?

As I delve into the world of JavaScript frameworks, one common trend I've noticed is that elements like dialogs, tooltips, and alerts usually appear at the end of the body tag. With my own implementation of these UI elements, I am determined to make ...

Creating Dynamic HTML/DOM in Angular 14: A Guide for Adding New Items to a List

I am currently iterating through a list of items and displaying them within a div element. These items are rendered when the page initially loads. <button (click)="addCut()" mat-raised-button color="primary">Add New Cut</button ...

When you click, apply the hidden class to all the div elements

Is there a way to apply the .hide class to all .slide divs whenever the .option button is clicked? If so, how can I modify my JavaScript code so that all .slide divs receive the .hide class (if they don't already have it) upon clicking the .option bu ...