Execute the function only in response to changes in the data

I have a scenario where I am making an ajax call every 3 seconds to keep my app updated with rapidly changing information. However, the expensive function that I run inside the $.done() callback is causing my app to slow down. I want to optimize this process by only running the function if the data returned from the ajax call is different from what I already have in the data object. Can someone suggest the best approach in Vue.js for achieving this?

var app = new Vue({
  data: {
    people : []
  },
  methods: {
    loadPeople() {
        $.ajax({
            method: 'POST',
            dataType: 'json',
            url: base_url + 'users/getParticipants2/' + event_id
        }).done(data => {
        //this.people is an array
        //data is an array
        //I only want to do these two things if data is different from what I had in this.people previously
            this.people = data;  
            this.filterPeople();
        });
    }
  }
});

Answer №1

Vue provides a helpful tool that might be applicable in this situation. Internally, Vue utilizes a function called looseEqual, which can be accessed via _q export and invoked as this._q().

You can make use of this function to only update your property when the new data fetched differs from the existing data. Check out the demo below.

new Vue({
  el: '#app',
  data: {
    people: []
  },
  methods: {
  async fetchPeople() {
    let response = await axios.get('https://jsonplaceholder.typicode.com/users');
      if (this._q(this.people, response.data)) {
        console.log("data didn't change, no need to update");
        return;
      }
      console.log("data changed, updating");
      this.people = response.data;
    }
  }
})
<script src="https://unpkg.com/vue"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>

<div id="app">
  <button @click="fetchPeople">Fetch People</button>
  <ul>
    <li v-for="p in people">{{ p.name }}</li>
  </ul>
</div>

One downside is that this function is internal (indicated by the _ prefix), so it may undergo changes in the future. Initially, its implementation was:

function looseEqual(o1, o2) {
    return JSON.stringify(o1) === JSON.stringify(o2);
}

In case of any changes, you always have the fallback option to rely on.

Answer №2

After carefully reviewing your explanation and the coding conventions utilized in the snippet you provided, I have a few key suggestions that may offer some insight.

If the main purpose of your filterPeople() function is to filter and update the view, it's possible that you are approaching this task from the wrong angle.

In the absence of full knowledge regarding the operations of the filterPeople() function, my advice would be to consider defining a vue.js filter if your intention is indeed to conduct a filtering operation. For instance, let's assume you wish to apply the filterPeople filter on the list of participants returned.

Vue.filter('filterPeople', function (newer, older) {
   if (older == newer) {
       return older
    }

    // Otherwise, proceed with filtering and return 'newer' 

 });

var endpoint  = '/users/participants';

new Vue ({
    el: '#app',
    data: {
        participants: null,
        previous: null
    },
    methods:{
        getParticipants: function(){
               this.$http.get(endpoint).then(function(response){
                   this.previous = this.particpants;
                   this.participants = response.data;
                }, 
                function(error){
                  console.log(error.statusText);
                }
              })
          },
          mounted: function () {
            this.getParticipants();
         }
  });

A typical representation within your html might resemble the following example.

<div id="app">
     {participants | filterPeople(previous)}
<div>

This approach is merely a suggested course of action (represented in pseudo code format). Another viable option could involve using a v-if directive to display the binding effects with or without the filter.

Furthermore, there appears to be a discrepancy where you reference a getParticipants endpoint while employing an HTTP post method. Ideally, I would recommend naming the endpoint as /users/participants and utilizing a GET method for retrieving participants, along with a POST method (on the same endpoint) that accepts a JSON request body for participant creation. Naming an endpoint based on an action like getParticipants is less than optimal; instead, endpoints should reflect the resource they pertain to. Web service "methods" typically align more closely with SOAP principles.

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

Revolving mechanism within React.js

I am currently developing a lottery application using React.js that features a spinning wheel in SVG format. Users can spin the wheel and it smoothly stops at a random position generated by my application. https://i.stack.imgur.com/I7oFb.png To use the w ...

AngularJS Banner: Displaying Current Calendar Week and Increasing by 10 Days

I'm brand new to Angular and currently encountering some issues. Here's what I'm trying to create: I need to display the current Date: yyyy-MM-ss (Functional) I want to show the current Calendar Week: yyyy-Www (Not Working) When a butto ...

Why is it that the window object in JavaScript lacks this key, while the console has it?

let myFunction = function declareFunc() { console.log(this); // window console.log(this.declareFunc); // undefined console.log(declareFunc); // function body } console.log(this) // window myFunction(); I understand that the this keyword in a functio ...

JavaScript / Regular Expression: remove the initial <p> tag if it meets a specific condition

Whenever I receive HTML content from the API, it may come in different formats. Sometimes, it looks like this: <p>::type/12</p> <p>Some content</p> <p>Some more content</p> Other times, it might not have the first para ...

Setting the font size for the entire body of a webpage globally is ineffective

Technology Stack: Nuxt.js + Vuetify.js Problem: Unable to set global body font size Solution Attempt: I tried to adjust the body font size to 40px in ~/assets/style/app.styl: // Import Vuetify styling ...

What is the best method for storing decimal values as floating-point numbers?

I am currently developing a Vue project where I need to store variables in decimal numbers using point notation. For example, if I input 23,5 it should be saved as 23.5. function school (ind){ this['School Name'] = "", this['Subj ...

How can the value attribute be obtained from the click class?

$(document).on('click','.edit', function(){ var appid = $(this).getAttribute('value'); I am trying to figure out how to save the value of the "value" attribute for an image with the edit class. Can anyone help me with thi ...

When I try to display an image on my website from the storage/app/public directory, it doesn't appear on the server

After saving an image in storage/app/public on my local machine, I am able to view the image when running the website on localhost. However, when I try to access the website on the server, the image does not display and instead shows a '404 (Not Found ...

Pinterest-style Angular-UI-Router modal

I am currently working on an app that features a gallery showcasing similar functionalities to . In Pinterest, clicking on a pin displays the pin page above the existing gallery without any information about the background gallery shown in the URL. Users c ...

Tips for integrating Apache Solr with Cassandra without using DataStax Enterprise (DSE)

Embarking on a new project, I find myself utilizing Cassandra as the chosen DBMS, with Apache Solr serving as the search engine and Node.js powering the server scripting language. While I am well-versed in Node.js, Cassandra and Solr are unfamiliar territ ...

Fixed-positioned elements

I'm facing a small issue with HTML5 that I can't seem to figure out. Currently, I have a header image followed by a menu div containing a nav element directly below it. My goal is to make the menu div stay fixed when scrolling down while keeping ...

When $(.class) displays result, Javascript ceases execution

In the code snippet below, I am trying to load a group of products from a category when the user clicks on the .expandproducts button: $('.expandproducts').click(function(){ id = $(this).attr("data-id"); urlajax = document.location.origi ...

Dealing with Vue's performance problems when using input type color and v-model

I am encountering a problem with setting the v-model on an input of type color. Whenever I change the color, there is a noticeable drop in frame rate and the application's FPS spikes from 60 to 3. You can see it reflected in the Vue performance graph ...

Can you provide some insight on the app.vue file within vue?

When working with Vue, declaring text.vue in a file named app.vue will result in the contents of text.vue being applied to all pages. However, there may be certain pages where you do not want text.vue to be applied. Is there a way to achieve this? app. ...

What is the best way to extract text from a dynamically changing element using jQuery?

I've been struggling with a coding issue. Despite trying numerous approaches, I keep encountering the same problem where every new button I add ends up having the same text or, alternatively, nothing seems to work as expected. $j serves as my variabl ...

Is there a way to modify the background color of a button once it has been clicked, specifically using JavaScript?

I am looking to change the background color of a button that I have clicked on in my code. Do I need to use loops and conditions for this task? I attempted to access the first index, but I am unsure how to change the background color of other buttons. l ...

Experiencing a JSONP issue with an 'Access-Control-Allow-Origin' error

When working with PHP, I often use the following code to echo JSONP formatted data: echo $_GET['callback'] . '('.json_encode($arr).')'; In my AngularJS (JavaScript) code, I make a GET request like this: $http.get('http ...

Dynamic JavaScript button control based on time

I am currently working on an app and my goal is to have a feature where the user clicks a button, it will then disappear and only reappear after 24 hours. Here's my progress so far. <div class="buttons"> <p><button onclick="hide(); ...

Exploring the possibilities of utilizing dynamic components in Nuxt.js 3

I am attempting to display dynamic components but it is not functioning as expected. <component :is="comp" /> The variable comp contains the name of the component during the process (CardComponent). No error messages are being shown and n ...

Error message: 'Encountered issue with react-router-V4 and the new context API in React

Currently, I am experimenting with the integration of React Router V4 alongside the new React context API. Below is the code snippet I am working with: class App extends Component { static propTypes = { router: PropTypes.func.isRequired, ...