Why is the value not updating in Vue 3 when modifying an object?

I am working on a project that includes 2 components where I have implemented a query-based search filter.

  1. PostsList component:
<template>
  <div>
    <PostFilter @change-filter="setFilters" />
    <h3>Active filters</h3>
    <pre>{{ activeFilters }}</pre>
    <h3>Updated filters</h3>
    <pre>{{ updatedFilters }}</pre>
  </div>
</template>
<script>
import PostFilter from "../../components/posts/PostFilter.vue";
export default {
  components: {
    PostFilter,
  },
  data() {
    return {
      updatedFilters: {},
      activeFilters: {
        category: "",
        query: "",
        perPage: 5,
        page: 1,
      },
    };
  },

  methods: {
    setFilters(updatedFilters) {
      console.log("Active filters");
      console.log(this.activeFilters);

      console.log("Updated filters");
      console.log(updatedFilters);

      this.$router.push({ query: updatedFilters });
      if (this.$route.query.page) {
        updatedFilters.page = 1;
      }
      this.activeFilters = updatedFilters;
    },
    objectEquals(obj1, obj2) {
      for (var i in obj1) {
        // eslint-disable-next-line
        if (obj1.hasOwnProperty(i)) {
          // eslint-disable-next-line
          if (!obj2.hasOwnProperty(i)) return false;
          if (obj1[i] !== obj2[i]) return false;
        }
      }
      for (var j in obj2) {
        // eslint-disable-next-line
        if (obj2.hasOwnProperty(j)) {
          // eslint-disable-next-line
          if (!obj1.hasOwnProperty(j)) return false;
          if (obj1[j] !== obj2[j]) return false;
        }
      }
      return true;
    },
  },
};
</script>
  1. PostFilter component:
<template>
  <div>
    <select class="category" v-model="filters.category" name="category">
      <option value="" selected>All categories</option>
      <option
        v-for="(category, index) in categories"
        :key="index"
        :value="category.id"
      >
        {{ category.title }}
      </option>
    </select>
    <input
      class="search"
      v-model="filters.query"
      type="search"
      name="query"
      placeholder="Search..."
    />
    <select class="perPage" v-model="filters.perPage" name="perPage">
      <option value="5">5 items / page</option>
      <option value="10">10 items / page</option>
      <option value="15">15 items / page</option>
      <option value="20">20 items / page</option>
    </select>
  </div>
</template>

<script>
export default {
  emits: ["change-filter"],

  created() {
    const query = this.$route.query;
    if (
      query &&
      Object.keys(query).length > 0 &&
      query.constructor === Object &&
      this.hasFilterKeys(query)
    ) {
      this.filters = { ...this.filters, ...this.$route.query };
    }
    this.fetchCategories();
  },
  data() {
    return {
      filters: {
        category: "",
        query: "",
        perPage: 5,
      },
      awaitingSearch: false,
      categories: [],
    };
  },
  watch: {
    "filters.category": function (currentValue, oldValue) {
      if (oldValue !== currentValue) {
        this.emitFilters();
      }
    },
    "filters.query": function (currentValue, oldValue) {
      // eslint-disable-next-line
      if (oldValue != currentValue) {
        if (!this.awaitingSearch) {
          setTimeout(() => {
            this.emitFilters();
            this.awaitingSearch = false;
          }, 1000);
        }
        this.awaitingSearch = true;
      }
    },
    "filters.perPage": function (currentValue, oldValue) {
      if (oldValue !== currentValue) {
        this.emitFilters();
      }
    },
  },
  methods: {
    emitFilters() {
      let cleanFilters = this.cleanObject(this.filters);
      this.$emit("change-filter", cleanFilters);
    },
    cleanObject(obj) {
      for (var propName in obj) {
        if (
          obj[propName] === null ||
          obj[propName] === undefined ||
          obj[propName] === ""
        ) {
          delete obj[propName];
        }
      }
      return obj;
    },
    async fetchCategories() {
      this.categories = [
        {
          id: 1,
          title: "Anatomy",
        },
        {
          id: 2,
          title: "Biology",
        },
        {
          id: 3,
          title: "Algebra",
        },
        {
          id: 4,
          title: "Chemistry",
        },
        {
          id: 5,
          title: "Computer Science",
        },
        {
          id: 6,
          title: "English",
        },
      ];
    },
    hasFilterKeys(obj) {
      for (const key in this.filters) {
        // eslint-disable-next-line
        if (obj.hasOwnProperty(key) && obj[key] != "") {
          return true;
        }
      }
      return false;
    },
  },
};
</script>

Every time the filters are changed or updated, an API request needs to be sent. However, I am encountering the issue of receiving same values in both the activeFilters and the incoming filters from the setFilters() method of the PostsList component. Why is the old value of activeFilters being lost before setting new values in my case?

For a real working example with code snippets, you can visit here.

You can also view an example video below:

<blockquote class="imgur-embed-pub" lang="en" data-id="a/Y4gauRM"  ><a href="//imgur.com/a/Y4gauRM">Same object values on search</a></blockquote><script async src="//s.imgur.com/min/embed.js" charset="utf-8"></script>

Answer №1

The object references in chrome developer console are considered to be "alive".

Let's take a look at this scenario:

let y = {c: 'd'}
console.log("Live data", y);
y.c = 'e';

This code will display:

Live data {c: "e"}

instead of Live data {c: "d"}


To observe different values, you can utilize the spread operator when assigning a new object as the value of liveData in your use case:

this.liveData = {...updatedData};

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 is the best way to convert the <br /> tag name into a white space in sanitize-html JavaScript?

I have some HTML code that looks like this: "<p>Hello world!<br/>I am here</p>" I need to replace the code with the following output: "<p>Hello world! I am here</p>" Is there a way to achieve this using t ...

Using Inline Styling to Showcase a Background Image in a REACTJS Component

import React from 'react'; import Slick from 'react-slick'; import style from './Slider.module.css'; import {Link} from 'react-router-dom'; const SliderTemplates = (props) => { let template = null; const ...

What is the method for assigning a link to a variable in JavaScript?

As I develop a website featuring an HTML course, I've opted for a consistent format for each lesson or page. One detail I've been working on involves setting a link within a button to a variable enclosed in quotes. For instance, I utilize the cod ...

Error retrieving value from a multidimensional array in JavaScript (TypeError: Unable to retrieve property '0' of undefined)

While working with a multidimensional array in my code, I encountered an issue when accessing the values through arguments. Oddly enough, everything worked fine when running the code using repl. However, when I switched to npm 5.6.0 and node 8.4.0, it init ...

Problem encountered with Blueimp gallery and Twitter Bootstrap

Blueimp gallery is being used to showcase a set of 8 images on a website, divided into two rows. The 5th thumbnail (first image on the second row) appears broken, even though it can be seen in the carousel presentation. Here's the link to view the th ...

I am unable to make changes to my `<input type="file">` element

I've been struggling to modify this button, and even tried incorporating bootstrap javascript without success. Below is a snippet of the code I'm working with. Any guidance on how to achieve this would be highly appreciated. <html> < ...

Distinguishing between Javascript Array Objects and Array-Like Objects: An Elucidation

While attempting to convert an array-like object into a string using JSON.stringify, I discovered that the function was not working correctly when the array-like object was declared as an array object. For more clarity, please refer to the following --> ...

The event tooltip in fullcalendar does not show up as expected

Within my Laravel 5.8 / Bootstrap v4.1.2 / jQuery jQuery v3.3.1 fullcalendar v4.3.1 application, I am attempting to incorporate tooltips for events in the fullcalendar plugin. To achieve this, I referred to a specific example provided here: Sample Example ...

Is it possible to use an onclick function to input JavaScript values into a password entry box seamlessly?

Is there a way to input password values continuously using a JavaScript onclick function into a password field? I have two images, one 'Blue' and one 'Red', that trigger an onclick function with the following values: Blue= w3! Red= T4 ...

Searching for the nearest BBCode using JavaScript regex

After checking the suggested SO questions, none of them seem to address my issue. I have a small form textarea that allows for BBCODE formatting. For example: [url=http://www.derp.com/]link[/url] [url=http://www.derp.com/435]link[/url] When a link is hi ...

Is there a way in HTML to navigate directly to a specific element on another page, even if it is not currently visible

I have used an anchor to navigate to a specific element on another page from the current page. However, the specific element I want to navigate to is not currently visible because it is controlled by JavaScript to keep the page short. The element is only s ...

Adding conditional href based on a specific criteria to an <a> tag in AngularJs

I have been working on a menu list where some menus contain URLs and others do not. When a menu item includes a URL, the href attribute is displayed, otherwise just the span tag is shown. I tried checking it like this but ended up with href="#" when the me ...

Unable to convert form data into a serialized format using jQuery in Django

I'm currently working with a template <form method="POST" action="{% url 'ajax_question' %}" role="form" id="question-form"> {% csrf_token %} {% for answer in answers %} <div class="radio"><label name="answers ...

It appears that there may be an unhandled promise rejection for a request with ID 0, specifically a typeerror indicating that the body

import React from 'react'; import { FlatList, ActivityIndicator, Text, View } from 'react-native'; export default class DataFetcher extends React.Component { constructor(props){ super(props); this.state ={ isLoading: true} ...

Issue with AngularJS: Unable to add a new property to an object

Here is the Javascript code I am working with in an AngularJS controller: $scope.schedule = {} $scope.selectEquipment = function(equip) { //alert(equip); $scope.schedule.equipment = equip; } I am successfully receiving the equip variable, but fo ...

Delay in only a portion of the AJAX response

I created a chat application that is functioning correctly, but I am encountering an unexpected behavior. When a user sends a message, the user's name, time, and message should be displayed in order. However, currently, it seems like the username and ...

Using jQuery to duplicate elements by copying and pasting

I am facing a scenario where I need to dynamically create and manipulate a div element in my web application. The process involves appending the newly created div to another container upon clicking a button, followed by triggering a series of functions on ...

Utilizing Django custom template tags with the power of JavaScript

I have created a custom template tag that fetches the name and roll number of a student based on their ID. @register.inclusion_tag('snippet/student_name.html') def st_name_tag(profile, disp_roll=True, disp_name=True): #performing some calcu ...

Setting up Vue in Django application: Configuring Vue instance using static JavaScript files

I'm having trouble setting up the vue instance from a separate JavaScript file (rather than including the code in each HTML template). Here is an example of the template: <html> <head> <title>Cinema project</title> < ...

Migration in Vite: issue with exporting is not found

Currently in the process of transitioning from vue-cli to Vite with Vue 2.0. I have multiple JavaScript-generated files for handling GRPC communication, each accompanied by a corresponding declarative file due to my usage of Vue with TypeScript. Upon atte ...