When refreshing a JavaScript array of objects, it creates duplicate entries within the array

Currently, I am developing a chat application within a Vue project and experimenting with different features.

A fully-featured chat app must have the ability to live-update "seen" states. This means that when one user views the last sent message, the other user should see a previously grey dot next to their sent message change to the other person's profile picture (this is not crucial to the main issue).

I am utilizing socket.io to trigger various events back and forth as these updates occur.

The overall flow is working smoothly so far, except for one specific aspect:

 messagesArray.value.findLast(function (message: any) {
        if (message.showUnRead === true && message.senderID === data.senderID) {
          delete message.showUnRead;
          message.read = true;
        }
        if (message.showRead === true && message.senderID === data.senderID) {
          delete message.showRead;
          message.read = true;
         
        }

Initially, this code functioned well. However, when I introduced changes to object values, it resulted in duplicating itself within the array.

Instead of just updating the messagesArray.value's last object, it updated that object and then added another identical one after it.

This issue only arises when I include the object value manipulation functions ('delete message.showRead' or 'message.read').

My assumption is that the findLast() function returns the object itself and subsequently appends this returned object back into the array, causing duplication.

I would prefer not to use the array.pop() method as this interferes with animations that are set up using transitiongroup. Additionally, it seems redundant to modify an object's values, retrieve the object again, make changes, and then manually delete the duplicate. It may be more efficient to find a different approach.

Ultimately, my goal is to solely update specific key-value pairs of the located (findLast()) object.

Therefore, my question is:

  1. Is there a built-in function that accomplishes this task?

  2. If such a function does not exist, how should I tackle this problem without experiencing disruptive effects from using pop()?

Various methods like pop(), slice(), and splice() have been attempted, all resulting in unnecessary complications.

Answer №1

At the outset, I want to clarify that the issue in my code did not stem from the findLast() function or how I utilized it.

However, due to common oversight during debugging, I too have encountered incorrect solutions related to my (initially misidentified) problem,

It is important to remember that sometimes you struggle to find a solution because you mistakenly assumed that you had correctly identified the problem in the first place and simply could not find the solution.

I am currently working on a chat application that includes features like displaying "unseen" and "seen" states with either a grey circle or a small circle containing the other user's profile picture. The system utilizes mongodb as an off-server message database and socket.io for real-time communication.

The app consists of a "parent" module where users can input text to send to each other and a "child" module where messages are displayed on the left or right side of the container based on whether they were sent or received by the current user.

In the "child" module, messages are stored in an array that is initially retrieved from the server upon first rendering. This array is updated on both ends using socket.io triggers only when the other user is actively present in the chat window.

Each message is represented as an object containing the actual message, date, senderID, sendToID, and a default "read" key set to "false".

The issue arose when I triggered the following sequence back and forth via socket.io:

  1. The sender sends a message (updating the mongodb database with a default "read" value of "false") --> additionally, the sender's child component receives the newly sent message through props, updates its own messagesArray with the new message using Vue's watch functionality

The child component receiving the message

    watch(
      () => props.selfMessage,
      (newvalue) => {
      
        messagesArray.value.push(newvalue);
      },
      { deep: true }
    );
  1. The receiver gets the message via socket.io, updating their own array with the message
  2. The receiver's script checks if the new message has a "read" status of "false" using Vue's vElementVisibility function. When the message is initially received and in view, it changes the "read" state to "true" and sends a "readMessage" trigger via socket.io
  3. The original sender receives the "readMessage" trigger, thereby updating their messagesArray's last message (which always represents the latest sent message) by changing the "read" status to "true" --> this triggers the rendering of a grey circle next to the profile picture

During step 4, the code mentioned in the original query was as follows:

    props.socket!.on("messageRead", function (data: any) {
       messagesArray.value.findLast(function (message: any) {
    if (message.showUnRead === true && message.senderID === data.senderID) {
      delete message.showUnRead;
      message.read = true;
    }
    if (message.showRead === true && message.senderID === data.senderID) {
      delete message.showRead;
      message.read = true;
     
    }

    });

During this final process, the "messageRead" trigger executes a function that modifies the most recently added message object - originally pushed into the messagesArray by appending the selfMessage's new value from the parent module into the array

Essentially, this is what I discovered through trial and error: I should not directly push the new value from selfMessage into the messagesArray because doing so would inadvertently trigger the Vue watch function again. Instead, I need to create a copy of the new value and insert that into the messagesArray

    watch(
      () => props.selfMessage,
      (newvalue) => {
       
        const newMessage = { ...newvalue };
        messagesArray.value.push(newMessage);
      },
      { deep: true }
    );

The lesson learned here is that when dealing with complex processes, it is crucial to revisit the foundational aspects where the process originates. Sometimes, overlooked details combined with existing methods can lead to unexpected issues.

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

I created an image that can be clicked on, but unfortunately it only functions properly on the

I am currently working on creating an image that can be clicked to cycle through different images all within the same frame. While I have managed to get it to work, I am facing a limitation where it only responds to one click. count = 1; function myF ...

Instead of scrolling through the entire window, focus on scrolling within a specific HTML element

I currently have the following elements: #elementA { position: absolute; width: 200%; height: 100%; background: linear-gradient(to right, rgba(100,0,0,0.3), rgba(0,0,250,0.3)); z-index: 250; } #containerofA { position: fixed; ...

Real-time data feeds straight from JSON

Currently, I have a JSON file that is generated dynamically and it contains match information along with a unique id. This JSON data is categorized into live, upcoming, and recent arrays. Being new to Javascript, I am unsure about the best approach to crea ...

Exploring the Possibilities with NodeJS and Socket.IO

I've encountered an interesting issue with my use of NodeJS and Socket.io. The server receives data through ZeroMQ, which is working perfectly fine. However, when there are a large number of connected clients (over 100), it appears that there is a de ...

The Nuxt Content Shiki plugin encountered an ERROR: "Page not found at /home"

I'm having issues getting syntax highlighter to work with @nuxt/content and Shiki. Once I installed the shiki package in my project's nuxt.config.js file. import shiki from 'shiki' ... export default { modules: ['@nuxt/content ...

Ensure that you wait for all asynchronous $http requests to finish in AngularJS before continuing

I am facing a challenge with a page that generates a varying number of $http requests based on the length of a certain variable. I aim to update the scope with the data only after all requests have been completed. Without relying on jQuery for this project ...

Encountered an issue with resolving the module specifier while attempting to import a module

Whenever I attempt to import a module, I consistently encounter this error message Failed to resolve module specifier "mongodb". Relative references must start with either "/", "./", or "../". and I have searched ext ...

Changing JavaScript array elements from strings to objects

While working with React, I am facing a challenge in creating an order/sort array to be sent to Node.js. The situation demands sorting by a specific table column. Here is what I have in React: sort = `[[Contact, "phone1", "asc"]]` This ...

I am converting a class component to a functional component within a React-Redux-Firebase project

I am currently in the process of rebuilding this component. Check out the updated code here Also, take a look at the project actions script here However, I'm facing an issue with rewriting mapStateToProps and mapDispatchToProps functions. The error ...

Encountering difficulties while attempting to delete with a router.delete command - receiving a 404 not

Within my application, I am passing the request parameter 'id' in the router.delete method and communicating it with the Vuex service. However, when triggering the action, an API call is made but it results in a 404 error indicating "not found" a ...

The Javascript Image() function fails to load or render

I am currently in the process of developing a basic Sprite class for implementation in a canvas game. However, I am encountering an issue where the image specified during the creation of a new instance of the class does not trigger the onload or onerror ev ...

Eliminate the unnecessary code repetition in my functions using Typescript

I have 2 specific functions that manipulate arrays within an object. Instead of repeating the same code for each array, I am looking for a way to create reusable functions. Currently, my functions look like this: setLists(): void { if (this.product.ord ...

Update the DIV element's class to reflect whether the quiz answer provided is correct or incorrect

I am facing a challenge while attempting to assign a CSS class to a dynamically created element in JavaScript. The error I'm encountering pertains to the reference issue with the trackerMarker element within the event listener functionality. Although ...

Discovering the geographical location of all users using Node.js: A step-by-step guide

My current task involves determining the geoip location of users. I have implemented a code that stores the user's address in the database and then displays the geoip location accordingly. However, if a user changes their location and logs in from a d ...

Retrieving precise passed arguments in the $(document).ready function

I am working on a gridview where I need the rows to expand and display the BatchID that is passed. Currently, I am using href="javascript:switchViews('div<%# Eval("BatchID")%>', 'one');" to pass this information, but I'm stru ...

How do I remove all elements from the Canvas in R3F?

I need a way to clear all models from the Canvas with just one click and then switch over to a new Canvas. I want to make sure that all items are removed from memory before making the change. Is there a way to accomplish this? return ( <div clas ...

Exploring the geographical boundaries of a Google Map region using coordinates and polygons

In my quest to develop an Angular application heavily reliant on Google Maps, I aim to showcase areas on the map based on continent -> country -> state -> suburb. The color of these highlighted areas will be determined by the values supplied. I h ...

Incorporate text/sentences from a file into a collection of strings in C

Being a novice programmer, currently enrolled in university, I have been assigned the task of creating a text-based adventure game in less than 2 months of studying programming. The requirement is that the game's text should be stored in a file. Init ...

Exploring the Boundaries of JavaScript Libraries

Exploring the inner workings of JavaScript libraries has been a challenge for me. Despite having some background in Java and JavaScript, I find the code below quite perplexing. These snippets are extracted from an example on david-tang.net's website. ...

locate the presence of a specific letter within a sequence of characters

When dealing with strings like "Galley1", "Galley2", "Galley3", "Galley4", "Galley5", "Galley6" up to "Galley20", the task is to determine whether a condition is met. The condition should return true if the string contains a number between 1 and 7, inclusi ...