Managing state in a live chat application

Currently seeking advice on managing state in a real-time messaging/chat app created with VueJS 2.

The application is made up of multiple components as shown in the diagram below:

https://i.sstatic.net/VGTo8.png

Up to this point, I have successfully implemented the display of (fake) conversations. Each conversation object is stored in an array within the App component and passed to child components through props, which works seamlessly.

Now, I am faced with handling actions/mutations from deeply nested components within the hierarchy. For instance, sending a message and adding it to the appropriate messages array.

I initially thought I could simply dispatch a global event from the AppConversationChatWindowInput component and handle it in the App component. However, I soon realized that this feature was removed with the introduction of Vue 2.0 in favor of Vuex. This change left me questioning its necessity, as there are situations where this approach would be suitable for event management.

I see a few potential solutions:

  1. Passing the websocket connection to each child component. While technically possible, this strategy feels suboptimal. The App connecting to the websocket server and passing the connection down via props to all child components may lead to a convoluted and difficult-to-maintain architecture. In my view, only the App should be aware of the websocket connection details.

  2. Manually propagating the event through each component in the hierarchy. Although feasible, this method introduces complexity and increases the likelihood of errors. It complicates the maintenance process unnecessarily.

  3. Utilizing a global event bus. While a viable option, relying on a global event bus for an input field seems excessive. Unnecessary dependencies and coupling can make testing and debugging more challenging.

  4. Employing a global data store (Vuex). Similar to #3, introducing Vuex adds another layer of complexity and dependency. Moreover, if opting for Vuex, determining how data is accessed by components becomes crucial. Should data be passed down through components or directly fetched from the store deep in the component hierarchy? This approach may result in components holding more information than necessary.

Any insights or recommendations on the most effective way to manage state in this scenario?

Answer №1

When considering the scenario of wanting to dispatch a global event without relying on a global event bus, it may seem contradictory. However, utilizing a global event bus is a common method for handling global events effectively. While it can be a valuable solution in certain situations, there is no strict requirement for it to be a core feature of Vue.

To implement a global event bus without using a global bus specifically, you can create it as an instance property on Vue, making it accessible to all components:

Vue.prototype.$globalEventBus = new Vue();

Instead of calling vm.$dispatch(...), you would utilize vm.$globalEventBus.$emit(...) and set up event listeners with vm.$globalEventBus.$on(...) in the receiving component.

Alternatively, you could pass a bus created at the top level down to children components as a prop, avoiding the need for global variables and ensuring events are handled appropriately without bubbling concerns.

Additionally, native events naturally bubble up through the component hierarchy, allowing you to intercept them at any level by binding native events to components. You have the flexibility to capture specific events related to messaging or even create custom events for catching purposes.

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

Send back Complex data type to display using AJAX

My Objective I am dealing with a complex type generated by EF from a stored procedure. This type returns a list of GetAvailableRooms_Results. I want the user to choose two dates and then get a list of available rooms (complex type) returned by the stored ...

"I encountered an error while sorting lists in Vue 3 - the function this.lists.sort is not

Creating a Vue 3 front-end template: <template> <div class="container"> <router-link to="/user/create" class="btn btn-success mt-5 mb-5">Add New</router-link> <table class=" ...

Utilizing jQuery to extract the id and update its content

One of my tasks involves working with a table generated by PHP and incorporating a modal that allows users to change the text produced by the variable $l_id. I have a link with a class "eloc" that triggers the display of the modal div section. By intercept ...

"Enhance input functionality by updating the value of the text input or resizing the textbox

I've been facing a challenge with updating the value of my input type=text or textbox control text value using jQuery $(window).resize(function(){});. I am aware that the event is triggered because an alert pops up when I resize the browser. Additiona ...

ReactJS attempting to invoke a class function using a dynamically generated button

When attempting to access the deletePost(index) method from the ShowPost class using a dynamically rendered button within the render() step in React, I encounter an issue. The button labeled "click me" successfully retrieves and prints the first item in my ...

Tips for testing views in ember.js using unit tests

We are currently delving into the world of Ember.js. Our development process is completely test-driven, and we aim to apply the same methodology to Ember.js. Having prior experience in test-driven development with Backbone.js apps using Jasmine or Mocha/Ch ...

Example when a specific $scope.apply() is needed:

I am currently delving into the world of Angular and experimenting with different ways to learn how it functions. One of my projects involves creating a simple application where users can add new entries through an HTML interface, store them in a SQLite da ...

Show a visual representation when Blob is retrieved from an API call

Currently, I am working on a Vue app that integrates with the Microsoft Graph API and SDK for authentication at the front end, along with using various features of the API like displaying emails, OneDrive files, etc. One specific challenge I am facing is ...

Guide to triggering a change event on a react-number-format component

I am attempting to trigger a change event in order to modify the value of a react-number-format component within my component. During testing, I encounter a TypeError: value.replace is not a function error on the simulate('change', event) method ...

Creating specialized paths for API - URL handlers to manage nested resources

When working with two resources, employees and employee groups, I aim to create a structured URL format as follows: GET /employees List employees. GET /employees/123 Get employee 123. GET /employees/groups List employee groups. GET /employees/groups/123 ...

Having difficulty invoking a JavaScript function through PHP

My goal is to achieve the following: <html> <script type="text/javascript" src="jquery.js"></script> <a id="random">before</a> <script> function test(a) { document.getElementById('random').innerHTM ...

Organizing Parsed JSON Data with JavaScript: Using the _.each function for Sorting

var Scriptures = JSON.parse( fs.readFileSync(scriptures.json, 'utf8') ); _.each(Scriptures, function (s, Scripture) { return Scripture; }); This code extracts and displays the names of each book from a collection of scriptures (e.g., Genesis, ...

Update text displayed on radio button selection using jQuery

Is there a way to change the label text on a selected radio button from "Set default" to just "default" using jQuery? I think I need to use the class radio-default as the selector, but I'm not very familiar with jQuery. <div class="radio-default ...

Unable to create a clickable button within a CSS3DObject using Three.js

How can I create an interactive button on a CSS3DObject within a cube made up of 6 sides? The button is located on the yellow side, but I'm facing issues with clicking on it. Whenever I attempt to click on the button, the event.target always points to ...

Utilize Firebase Hosting to Host Your Vue Application

Having some trouble with hosting code on Firebase. Instead of displaying the value, {{Item.name}} is appearing :( Same code works fine on Codepen. Wondering if Firebase accepts vue.min.js? When deployed, the site is showing {{var}} instead of the table va ...

The modal remains visible

Has anyone encountered a problem with hiding a Bootstrap modal based on form validation in JavaScript? I'm facing an issue where the submit function is not executed when I click the button. I've attempted using onsubmit=validateForm(), but it doe ...

I struggle to format a classic HTML form dropdown menu that is populated using JavaScript

Hey everyone, I'm having an issue with styling a drop down menu that is populated by JavaScript. I've tried different things but nothing seems to be working. Any suggestions on how I can style the elements in the drop down? <form action="" me ...

Utilize Node JS to assign variables to HTML form inputs

Can anyone help me with storing HTML form inputs in variables using Node JS? I'm having trouble getting it to work properly. Below is the HTML form snippet: <form action="localhost:8080/api/aa" method="post"> <input id="host" type="text ...

Dynamic routing with ngIf in Angular 2's router system

Is there a way to use *ngIf with dynamic router in Angular? Let's say I have a top navigation component with a back button, and I only want the back button to be visible on the route 'item/:id'. I tried using *ngIf="router.url == '/ite ...

In a peculiar occurrence, the behavior of array.splice is exhibiting unusual characteristics within an

Be sure to take a look at this plunkr for reference: http://plnkr.co/edit/FQ7m6HPGRrJ80bYpH8JB?p=preview I'm encountering an issue where, after adding an element and then deleting it from the array using the splice method, everything becomes disorg ...