Ensuring that computed value is updated only once in Vue composition API while observing multiple interconnected references

How can we efficiently trigger a costly recalculation only once for a computed value that depends on multiple references, where one reference is dependent on the other?

For example:

In the following scenario, I aim to compute expensiveData only once. The value of expensiveData gets recalculated when either varA or varB changes. However, varB is derived from varA, so any change in varA will result in a change in varB.

import { ref, watch } from '@vue/composition-api';

// Definition of varA, updated with fetched data changes
const varA = ref([
  /* some data */
]);

// Definition of varB, derived from varA but independently modifiable
const varB = ref(null);

// Derive varB based on varA's value
const updateVarB = (a) => {
  const varBValue = /* process varA */;
  varB.value = varBValue
};

// Update varB when varA changes
watch(varA, (newVarA) => {
  updateVarB(newVarA);
});

export { varA, varB, updateVarB }

some-other-file.js

...
// Change varB upon a user-triggered event
const someData = ...
updateVarB(someData);

expensive-calc.js

import { computed, toRefs } from '@vue/composition-api';
...
/* varA and varB are passed as props */
const { varA, varB } = toRefs(props);

const makeExpensiveData = (...args) => /* some heavy lifting */

const expensiveData = computed(() => {
  /* Perform calculations with varA and varB */
  return makeExpensiveData(varA.value, varB.value)
});

What strategies can be employed to ensure that expensiveData is recomputed just once?

Key considerations:

  • varA and varB have distinct meanings, making it unsuitable to create a single computed value combining them.

The current workaround involves debouncing the call to makeExpensiveData using lodash.debounce. As varB is derived from varA, they trigger reevaluation together.

However, being fairly new to Vue's composition API, I am curious about better solutions for addressing this issue.

Answer №1

Assuming that varB will always be updated after varA, you have the option to swap out the computed with a ref along with a watch.

const resultData = ref(null);

watch(
  varB,
  () => resultData.value = generateResult(varA.value, varB.value),
  { immediate: true } // <- if you need instant access
);

Nevertheless, is this issue still repeatable?

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

What methods does Stack Overflow use to achieve rapid execution of Ajax features on its website?

I am amazed by the lightning-fast Ajax functionality on Stack Overflow. From voting to commenting, answering, approving edits, and even editing questions and answers, everything runs so smoothly with incredible speed. In our usual scenarios, making an Ajax ...

Troubleshooting Autocomplete User Interface Problems

I am currently working on a website user interface and I have encountered an issue specifically in IE7. When searching for a company, the display is not showing up correctly, as demonstrated in the image below. This problem only occurs in IE7, it works fi ...

Inquiry regarding the ng-disabled directive in AngularJS

<div ng-app="myApp" ng-controller="myCtrl"> <button type="submit" class="btn btn-primary pull-left" ng- disabled="captchaError">Submit</button> </div> <script> var app = angular.module('myApp', []); app.controller( ...

Troubleshooting JavaScript AJAX: Challenges with the GET Method in Web API Core

Struggling with a basic ajax method and feeling lost without proper backend explanation in tutorials used for work. Seeking to display a message from the backend along with additional text and a corresponding message. Currently working with HTML/CSS/Java ...

Custom component is experiencing issues with radio buttons not maintaining the checked state

Currently, I am facing an issue where checking either Male or Female results in both options getting checked. This problem didn't occur with the previous v-model approach. In addition, I would appreciate guidance on whether it is possible to include ...

Creating Structure with Highcharts - Sorting Through Unprocessed Data

In reviewing various demos of highcharts, I noticed that they all tend to adhere to a fairly straightforward data structure: Categories,Apples,Pears,Oranges,Bananas John,8,4,6,5 Jane,3,4,2,3 Joe,86,76,79,77 Janet,3,16,13,15 However, the data I have doesn ...

Exploring Firestore: Tips for Locating an Email Across Multiple Documents

My task is to locate the ID of a document by comparing the email contained in each document. Below is the database I am working with: https://i.sstatic.net/PLElW.png As an example, let's say I have the email "[email protected]", but ...

Vue.js is experiencing issues with the error message stating that "Auto-populating $HTTP_RAW_POST_DATA is deprecated and will be removed in a future update."

I am currently using Laravel 5.4 for my backend and Vue.js for the frontend of my project. I am trying to pass values from Vue to the controller to store data, however, on checking the console, an error is being displayed. The warning about automaticall ...

What is the best way to find the index of a row in a Bootstrap Vue table?

When working with a v-for in Vue, I typically do it like this: v-for="(test, index) in tests" Is there a way to achieve the same result using Bootstrap Vue? Specifically, how can I access the index of all TR elements? <b-table :items="items" :field ...

Controlling JavaScript Text Opacity on Scroll: Smooth Transitions from Invisible to Visible to Hidden

I am attempting to replicate the Apple Airpods page, including its animation. I have successfully implemented the animation and now I am working on rendering text while scrolling. The text appears correctly but I'm facing an issue with opacity transit ...

Issue in JavaScript on IE9: SCRIPT5022 error: DOM Exception - INVALID_CHARACTER_ERR (5)

I am encountering an error with the following line of code: var input2 = document.createElement('<input name=\'password\' type=\'password\' id=\'password\' onblur=\'checkCopy(th ...

Retrieving the source code via JQuery Ajax

I've been implementing JQuery Ajax on my website and encountered an issue. It's working perfectly fine on our test server, but when I transferred it to our live server, the Ajax response is just the source code of the website itself. Here's ...

An issue has occurred in Angular pipe: TypeError - array.map is not functioning as expected

I encountered the following error: ERROR TypeError: array.map is not a function, while using this angular pipe. Here is the code snippet: export class CharacterWithCommasPipe implements PipeTransform { transform(array) { return array.map(item => ...

Can you explain the functionality behind the expression "this.method.bind(this)"?

Encountered the code for the first time: var Controller = function($scope){ this._scope = $scope; } Controller.$inject = ['$scope']; Controller.prototype.augmentScope = function() { this._scope.a = { methodA: this.methodA.bind( ...

When ran automatically as a cron job, the JavaScript script fails to establish a connection with MongoDB

As I connect to mongodb (on a Ubuntu machine) from a js script, everything runs smoothly when I execute the command from the command line (node <name of the script>). However, when I try executing the same command from cron, the connection times out: ...

Learning how to effectively incorporate two matSuffix mat-icons into an input field

I'm currently experiencing an issue where I need to add a cancel icon in the same line as the input field. The cancel icon should only be visible after some input has been entered. image description here Here's the code I've been working on ...

Formulate an array and filter out items that conclude with a colon

I have an array that needs filtering to remove all objects ending with a colon. Is there a simple way to do this, such as implementing it in the existing filter function? var ingredientsArray = ingredients.replace(/<strong>[\s\S]*?<&bso ...

Is there a way to set formArray values back to their default values without using form.reset(), which sets them to null?

I am a beginner when it comes to using Angular and I am currently dealing with a form that consists of the following fields. this.catform = new FormGroup({ name: new FormControl('', Validators.required,), source: new FormControl('' ...

When the icon is clicked using `ngClick`, we are triggering the `refresh` event, but unfortunately, it is not functioning as expected

Currently, I am utilizing Angular and jQuery float to create a canvas graph. The graph itself is composed of canvas elements. The issue at hand involves the desire to redraw the canvas upon clicking on a specific icon. The click event handler in question ...

The reason behind the issue of Too many re-renders caused by the useState react hook is due to React's limitation on the number of renders in order

In my code snippet below, I am encountering an issue: const [customers, setCustomer] = useState([]); if(users.results){ users.results.filter(user => { user.roles.filter(role => { if(role.role.name === 'ADMIN'){ ...