VueJS: Troubleshooting Issues with Array Updates

Presented below is the HTML code structure

<template>

 <div id="left_container" ref="usersContainer">
  <button v-for="user in users" :key="user.userID" >{{ user.username }}</button>

</div>
<div id="right_container">
    <ul id="messages"></ul>
    
    <div id="bottom_container">
    
    <label id="lt"></label>
    <form id="form" @submit.prevent="onSubmit" action="">
    <input id="input" v-model="in_msg" autocomplete="off" v-on:input="vChanged"/><button>Send</button>
    </form>
  
</div>
</div>

</template>
  
  <script>
  import socket from "../socket"
 
  
  export default {
    name: "MyChat",
    components: {
     
    },
    data() {
      
      return {
        in_msg:'',
        users: [],
        selectedUser: null,
      };
    },
    methods: {
      onSubmit()
      {
        console.log(this.users);
        if(this.selectedUser)
        {
          var content = this.in_msg;
          socket.emit("private message", {
            content,
            to: this.selectedUser.userID,
          });
    
        }
        else{
        if (this.in_msg) {
          socket.emit('chat message', this.in_msg);
          this.in_msg = '';
        }
       }
      },
      vChanged()
      {
        socket.emit('on_c');
      },

      
    },
    created()
    {
      
      var messages = document.getElementById('messages');
      var lbl_writing = document.getElementById('lt');
      
      socket.on('chat mess', function(msg) {
        
        var item = document.createElement('li');
        item.textContent = msg;
        messages.appendChild(item);
        window.scrollTo(0, document.body.scrollHeight);
      });
      socket.on("private message", ({ content, from }) => {
        var msg = from + " : " + content;
        var item = document.createElement('li');
        item.textContent = msg;
        messages.appendChild(item);
        window.scrollTo(0, document.body.scrollHeight);
  
});
      socket.on('chat message not', function(msg) {
       lbl_writing.textContent = msg;
      });
      socket.on('users',function(users)
      {
       
        this.users = [...users];
        console.log(this.users);
        //const dlv = document.getElementById('left_container');
        //dlv.innerHTML = '';
      //   this.users.forEach(user => {
      //   const button = document.createElement('button');
      //   button.innerHTML = user.username;
        
      //   //button.addEventListener('click',this.onClick(user));
       
      //   //dlv.appendChild(button);
      // });
      });
      socket.on('user connected',function(user)
      {
       
        this.users.push(user);
        // const dlv = document.getElementById('left_container');
        // //dlv.innerHTML = '';
       
        // const button = document.createElement('button');
        // button.innerHTML = user.username;
        
        // //button.addEventListener('click',this.onClick(user));
       
        // dlv.appendChild(button);
    
      })
    }
   
  };
  </script>
    <style scoped>
 
    #left_container {width: 19vw;position: absolute;top: 0;bottom:0; background-color: white;border: dashed black;display: flex;flex-direction: column;}
    #right_container {width: 80vw;display: flex; background-color:white;flex-direction: column;position: absolute;margin-left: 19.5vw;top:0;bottom: 0;}
    #bottom_container { display: flex; position: absolute; bottom: 0;left: 0;right: 0; flex-direction: column;}
    #form { background: rgba(0, 0, 0, 0.15); padding: 0.25rem; display: flex; height: 3rem; box-sizing: border-box; backdrop-filter: blur(10px); }
    #input { border: none; padding: 0 1rem; flex-grow: 1; border-radius: 2rem; margin: 0.25rem; }
    #input:focus { outline: none; }
    #form > button { background: #333; border: none; padding: 0 1rem; margin: 0.25rem; border-radius: 3px; outline: none; color: #fff; }
    #pv { background-color: red;color: #fff;}
    #lt { background: rgba(0, 0, 0, 0.15); padding: 0.25rem; display: flex; height: 3rem; box-sizing: border-box; backdrop-filter: blur(10px); }
    #lo { background: rgba(0, 0, 0, 0.15); padding: 0.25rem;  display: flex; height: 3rem; box-sizing: border-box; backdrop-filter: blur(10px); }


    #messages { list-style-type: none; margin: 0; padding: 0; }
    #messages > li { padding: 0.5rem 1rem; }
    #messages > li:nth-child(odd) { background: #efefef; }
    .user-button {
  background-color: blue;
  color: white;
}

  </style>
  

The issue arises when trying to update the 'users' array within the template section as it's not reflecting any changes despite attempts made in socket.on('users'). Even after execution of that function, the 'users' array remains empty.

Answer №1

Vue provides a way for the page elements to react to changes in variables without the need to directly manipulate the DOM using methods like getElementById, createElement, or appendChild.

Just like how you handle displaying the list of users, utilize Vue's data to manage an array of messages and a string for the label text.

<template>
  <div id="left_container" ref="usersContainer">
    <button v-for="user in users" :key="user.userID" >{{ user.username }}</button>
  </div>
  <div id="right_container">
    <ul id="messages">
      <!-- Using the array index as a key is not recommended, but 
           it will work for simple array appending -->
      <li v-for="(message, index) of messages" :key="index">
        {{ message.msg }}
      </li>
    </ul>
    <div id="bottom_container">
    <label id="lt">
      {{ lbl_writing }}
    </label>
    <form id="form" @submit.prevent="onSubmit" action="">
      <input id="input" v-model="in_msg" autocomplete="off" v-on:input="vChanged"/><button>Send</button>
    </form>
  </div>
  </div>
</template>

The script simply updates the messages and lbl_writing variables instead of making direct modifications to the elements themselves.

<script>
import socket from "../socket"

export default {
  name: "MyChat",
  data() {
    return {
      in_msg:'',
      users: [],
      selectedUser: null,
      messages: [],
      lbl_writing: null,
    };
  },
  mounted()
  {
    socket.on('chat mess', function(msg) {
      this.messages.push({ msg })
    });
    socket.on("private message", ({ content, from }) => {
      var msg = from + " : " + content;
      this.messages.push({ content, from, msg })
    });
    socket.on('chat message not', function(msg) {
      this.lbl_writing = msg
    });
    socket.on('users',function(users){
      this.users = [...users];
      console.log(this.users);
    });
    socket.on('user connected',function(user)
    {
      this.users.push(user);
    })
  }
};
</script>

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

Utilizing Angular and Cordova within a Virtual Directory

In an Angular application running in a virtual directory (https://{url}/{virtualDirectory}), I am attempting to encapsulate it within a Cordova application that references the same URL as the content source (<content src="https://{url}/{virtualDire ...

Creating a div background that is transparent within a Bootstrap modal

Here is the HTML (Bootstrap) code I have: <div modal="showModal" close="cancel()"> <div class="modal-header text-center"> <h2>Members who shortlisted you </h2> </div> <div class="modal-body"> ...

When the loop is malfunctioning due to a certain condition

what happens if the condition in the controller file is not executed during runtime... ...

What is the best way to connect a React application with a mailerlite.com signup form?

Looking to seamlessly incorporate an email signup form from Mailerlite.com into your website? Wondering how you can integrate this functionality with React? In particular, are you curious about the process of integrating the JavaScript code required for t ...

The art of masonry meets the versatility of dynamic tabs in

On a webpage, I have dynamic tabs that display different content based on what the user selects. I want to use Masonry layout to make this content look visually appealing. The issue arises when a user switches tabs and the content collapses, as shown here ...

The error message says: "Unable to access attributes of an unknown object ( 'ownerDocument' )"

I am currently working on using htlm2canvas in Vue.js to capture a screenshot of a specific div, but I keep encountering the following error: Cannot read properties of undefined (reading 'ownerDocument') Should I be importing something within t ...

Reactjs encountering issues loading css file

Currently, I am working on a project in Reactjs with Nextjs. To add CSS to my project, I have stored my CSS files in the 'styles' folder. In order to include them, I created a file called '_document.js' and implemented the following cod ...

How can one retrieve data from two distinct API routes within a Next.js application?

Currently, I am working with Next.js and facing a challenge in fetching data from two different API routes simultaneously. My intention is to retrieve this data within the getServerSideProps function. The first dataset that I require can be found at the e ...

What is the process for logging in or authenticating before running tests with pa11y-ci?

Is there a way to authenticate users and test pages using pa11y-ci? When running pa11y-ci, I typically use this command: pa11y-ci --sitemap http://www.example.com/sitemap.xml --sitemap-find https --sitemap-replace http I came across some helpful informa ...

Using the POST method allows for sending a distinct string from REACT to an API

I am experiencing an issue with my SQL query component. Whenever I send a query to the API-server, the backend crashes because MySQL interprets an empty string as my request. Interestingly, my backend works perfectly fine when tested using postman.exe. T ...

JavaScript encountering issues when parsing a string that was serialized using Gson in Java

This question is unique and differs from this one as it specifically addresses the representation of JSON strings serialized from Java in literal form in JavaScript, with a focus beyond just double quotes. In my scenario, I am serializing a JSON object in ...

How to convert two arrays into JSON strings and store them in variables using JavaScript

After receiving an ajax response in JSON format, my JavaScript code (within the ajax response success function) stringifies two arrays. Now, I need to assign the data from one curly bracket to two variables, and the data from the other curly bracket to ano ...

Issue with dynamic-rooms causing networked Aframe project to malfunction

I am currently working on a project using A-frame() along with the networked A-frame component: https://www.npmjs.com/package/networked-aframe To view the project, click here: I encountered an issue when attempting to replace the following code in scene. ...

Exploring the Depths of Scope Hierarchy in AngularJS

Upon inspecting the _proto__ property of an object I created, it is evident that it has been inherited from Object. https://i.stack.imgur.com/hcEhs.png Further exploration reveals that when a new object is created and inherits the obj object, the inherit ...

A guide to accessing real-time data in Vue.js

This is my debut project in Vue, and I am currently retrieving cart data from the server. My goal is to be able to modify the quantity using Vue. Right now, when I click on the up or down arrow to change the quantity, it gets reflected in the server databa ...

What is the best way to locate the key with the greatest value in an array that is less than or equal to a certain

In my data structure, I have an array that maps user levels to the minimum points required for each level. Here's how it looks: $userLevels = array(0 => 0, 1 => 400, 2 => 800); The keys represent user levels and the values represent the min ...

Ways to retrieve parameters in getStaticPaths function?

I'm currently working on a Next.js app with Contentful as the CMS. The file structure relevant to my question is: pages -[category] -[slug].js My goal is to access the category value when a user visits category/slug. Currently, I have the category ...

A guide to setting properties using a Proxy object

Within my class, I have included a Proxy which is structured as follows: export class Row<T extends ModelItems> { private _row: T = <T>{} public constructor(rowItems?: T) { if (rowItems) { this._row = rowItems } return new Proxy( ...

Retrieving objects based on a property that begins with any element from an array

I have a collection of contacts that I need to filter based on the country code. Specifically, I want to identify contacts whose phone numbers start with any of the selected country codes. var countries = ['1', '91', '55', &ap ...

The child element is absolutely positioned within the parent element with a higher z-index

It is crucial for the parent absolute to be under child absolute. How can I resolve this issue using CSS? The positions of both elements must remain absolute. <div class="parent"> <div class="child">child</div> </div> ...