Organizing methods to manage changes in universal and specific states

There are certain components in my application that do not need to store all their state globally. Let me provide you with two examples:

  • messages component: User messages are fetched and stored locally because they are only required for the current component's usage. However, if there is an error fetching the messages from the API, then the error needs to be dispatched to the global state (vuex).
  • buy component: The 'recent buys' information is fetched and stored locally, but the 'money' data should be dispatched to the global state. In case of an error while fetching recent buys, the error should also be dispatched.

I am currently trying to figure out how best to structure this setup and could use some assistance. I have a directory named services which contains API calls. Let's take the buy service as an example:

/services/buy.js:

// Code here to dispatch money state
// Code here to dispatch 'last activity' state

Vue.$http.get('/buy', credentials)
  .then((response) => {
    // Return recent buys
  })
  .catch((error) => {
    // code here to dispatch error state
  });

There are interdependencies between these services as well. For instance, after a successful purchase, a new message needs to be sent using /services/newMessage.js.

But where and how should I organize all of this logic? Let's consider the buy component as an example. Here are a few options:

#1: This corresponds to the above code

  • The buy component imports the buy service and executes it using newBuy()
  • The service dispatches the money to the global store and retrieves recent buys, returning them
  • In the component, the returned value from the service updates the local store
  • The component also includes logic: upon successful return, it triggers the message service to send a new message using sendMessage()

#2: The main difference from #1 is that the logic resides within the service

  • The component imports the buy service and calls it using newBuy()
  • The service dispatches the money to the global store and imports the message service
  • The message service sends a new message using sendMessage()
  • Returning to the buy service, recent buys are fetched and returned
  • The component now updates the local store with the retrieved value

#3: This differs from the aforementioned steps by including all Vuex-related actions in a dedicated actions.js file, thereby ensuring clear separation between global and local state updates

  • The component imports the buy service and executes it using newBuy()
  • The service imports ./store/actions.js and invokes the updateMoney() service to update the money in the global state
  • It can proceed with the steps outlined in #1 or #2

I would appreciate any guidance on how to effectively merge components that utilize both global and local states. Would any of the above three approaches be suitable for achieving this goal?

Answer №1

If you find yourself in a situation where global state sharing is unnecessary, then loading vuex's states with unnecessary data is not the best approach.

Imagine having 10 components similar to the buy component, each fetching only the specific state they require from the vuex store. This would make the vuex store more complex and difficult to understand.

Furthermore, if you start adding actions and mutations for these states, you may end up creating modules for each of the 10 components, further complicating your state management and logic.

Therefore, in this scenario, option 2 seems like a better choice if you are confident that the state retrieved won't be needed elsewhere. You seem to have a good understanding of why vuex is used, which is advantageous. Planning is crucial for larger applications, so mapping out how your app will function and identifying where connections need to be made before development can help you make informed decisions on what data should or shouldn't be pushed to vuex.

When comparing options 1 and 2, consider the scope and keeping things DRY (Don't Repeat Yourself). If every time you receive data from `newBuy` you have to call `sendMessage`, and the `buy-service` has the necessary data to populate the message, it indicates that the services should work together cohesively. As long as you write the `message-service` in a way that separates it from external dependencies unrelated to sending messages, integrating it with the `buy-service` is feasible.

Option 1 appears to duplicate a function that needs to be executed every time the buy service is called. It's advisable to avoid duplication to maintain clarity in your app structure and to facilitate future expansions without complications. Instead, focusing on how `newBuy` triggers `sendMessage` upon receiving data ensures simplicity and coherence in the application logic.


To provide additional context, consider following these steps:

  • The component imports the buy service and invokes: `newBuy()`
    • Calling `newBuy()` should return a promise to the component
  • The buy service imports the message service
  • The buy service retrieves data by calling `newBuy`, which calls `getMoney` and `getRecentBuys`
    • Both operations return promises, use Promise.all to await resolution of both endpoints and retrieve their data simultaneously

Upon resolution of the `newBuy` Promise.all:

  • `getMoney` returns data: The buy service dispatches the money to vuex module store
    • Create a vuex module if there are various types of data within the money store to enhance its manageability
  • The buy service calls the message service to send a new message using `sendMessage()`
  • The buy service resolves the promise by passing recent buys as payload
  • The promise resolves at the component, updating its local data with the received payload

Upon rejection of the `newBuy` Promise.all:

  • The buy service rejects the promise
    • Pass an empty payload or error message
    • Dispatch error to vuex store
  • The promise is rejected at the component, preventing updates to its local data

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

Ways to verify the occurrence of a successful event following the execution of a save() operation on a model

Below is the snippet of code I am using to store extra properties in a model (specifically, the answer model) selectMedia: => # Post media to server @options.answer.id = @options.answer.get('_id') @options.answer.url = "/v1/answers/#{@o ...

What is the primary function for Express.js and Node.js 10 in Google Cloud Functions?

My Node JS version is 10 Express JS version: 4.16.1 I understand that for Node JS 8, the entry point should be "app" The generated code (from `npm install -g express-generator) www #!/usr/bin/env node /** * Module dependencies. */ var app = require( ...

The alignment is off

<script> var myVar = setInterval(myTimer, 1000); function myTimer() { var d = new Date(); document.getElementById("demo").innerHTML = d.toLocaleTimeString(); } </script> <p text-align="right" id="demo" style="font-family:Comic Sans ...

When using DataTables ajax.reload with pagination enabled, the table content jumps to the bottom of the page

I am currently using jQuery DataTables with ajax sourced data. To ensure that the data remains up to date every 30 seconds without requiring a page refresh, I have been utilizing the ajax.reload() function. To achieve this, I have placed the ajax.reload() ...

Adding a background image in javascript using data from a MySQL database

My current tech stack includes CodeIgniter, vanilla JavaScript, AJAX, CSS, and MySQL. I am trying to figure out how to set the background of an image that is stored in a MySQL database. While the following code is error-free and working perfectly, my cha ...

What is the most effective method for managing the onSelect data within the select tag in Angular's reactive form functionality?

Can someone please advise on the best approach to handling this scenario? I have a form with multiple fields, including a select tag. <form [formGroup]="myForm"> <select formControlName="" > <option *ngFor="let c of countries" value ...

Is there a way to find the Nth occurrence of a specific weekday in each month between two given dates using JavaScript?

Within my program, users can set events with start and end dates, as well as the period of repetition: weekly, monthly by date, monthly by weekday, or yearly. Once an event is created, it's stored in the database and displayed on the main calendar pag ...

Does using ng-if with a select and ng-options cause issues with ngModel?

Check out this plunker showcasing Angular's ngOptions feature: Angular Select Options Plunker I decided to spice things up by adding an ngIf directive to the initial select element: <div ng-if="1<2"> Color (null not allowed): <s ...

Rest assured, with Ajax Security, your protection is in good

I am currently developing a browser game that heavily utilizes AJAX instead of page refreshes. The combination of PHP and JavaScript is being employed for this project. However, during the course of my work, I became aware of the potential security vulnera ...

Enhance your Vuetify v-data-table with intricate data integration

I am currently working on the v-data-table component and I'm having trouble processing information from the backend. Can anyone provide some assistance? I attempted to use this code, but I keep receiving the error: "vue.runtime.esm.js:1897 TypeError: ...

What is the method to select a hyperlink that includes a variable in the "href" attribute and click on it?

Currently, I am in the process of creating acceptance tests utilizing Selenium and WebdriverIO. However, I have encountered a problem where I am unable to successfully click on a specific link. client.click('a[href=#admin/'+ transactionId + &apo ...

Showing a collection of cards within a dynamic container set up in a 3x3 grid layout to start

In an attempt to showcase cards within a responsive container utilizing bootstrap and django, my goal is to create a 3x3 grid layout on extra-large screens with scrollable overflow that adjusts based on device width. Initially, I experimented with wrapping ...

Connection between the view and the router's backbone

In my opinion, it is important to maintain isolation between the router and view in data-driven programming paradigm. They should only communicate with each other through model changes that they both subscribe to. However, I have noticed that different on ...

Is it possible to use an if statement within the .map()

I am seeking guidance on how to incorporate an if statement inside .map() Please refer to the code snippet below for context. Currently, the delete button is disabled when the image is not uploaded by the current user, but my objective is to complet ...

Understanding how to implement action logic in React Redux to control visibility of specific categories

Seeking guidance on how to implement action logic for displaying and hiding elements based on user interaction. Currently, all categories and subcategories are shown at once, but I would like them to be displayed only when a user clicks on them. When a use ...

Switch out the Jquery modal trigger for VueJS

Currently learning Vue.js and attempting to convert a Jquery call to Vue.js. Hopefully, it's a straightforward process? Recently integrated the bootstrap-vue library with hopes of replacing the usage of JQuery. Interested in migrating the following ...

The text is not appearing properly in an HTML file due to issues with

Hi trying to display the text received from the controller's scope. Here's what I have attempted: HTML: <div ng-repeat="item in sResults"></div> Controller JavaScript: $scope.sResults = []; function App( ){ var Label ...

Tanstack onMutate Callback Fails to Activate Modal on React State Update

Currently, I am in the process of developing a Dapp and I need to incorporate transaction tracking. One issue I am facing is with trying to display a modal window when the approval setting process begins. Despite attempting to alter the isOpen state of the ...

Having trouble accessing the loadTokenizer function in Tensorflow JS

As a beginner with Tensorflow.js concepts, I recently attempted to tokenize a sentence using the Universal Sentence Encoder in Javascript. You can explore more about it on Github Reference $ npm install @tensorflow/tfjs @tensorflow-models/universal-sentenc ...

The feature of using a custom find command in Cypress does not support chaining

I am interested in developing a customized Cypress find command that can make use of a data-test attribute. cypress/support/index.ts declare global { namespace Cypress { interface Chainable { /** * Creating a custom command to locate a ...