Changing a variable within a method does not automatically reflect in the child component

Need help with Vue update process for props/child components.

Consider this component:

<template>
  <v-card>
    <Modification v-model="newObject"></Modification>
    <OtherComponent @close="resetObject"></OtherComponent>
  </v-card>
</template>

<script>
import { MyClass } from "classes";
import Modification from "b";
import OtherComponent from "a";

export default {
  name: "MyForm",
  components: { OtherComponent, Modification },
  props: {
    existingObject: {
      type: [MyClass, typeof undefined],
      required: false,
      default: undefined
    }
  },
  data() {
    return {
      newObject: undefined
    };
  },
  created() {
    this.newObject =
      this.existingObject !== undefined
        ? this.existingObject.clone()
        : new MyClass();
  },
  methods: {
    resetObject() {
      this.newObject =
        this.existingObject !== undefined
          ? this.existingObject.clone()
          : new MyClass();
    }
  }
};
</script>

Definition of MyClass:

export class MyClass {
  constructor({ a= null, b=null} = {}) {
    this.a = a;
    this.b = b;
  }
  toPayload(){
    return { a:this.a , b:this.b };
  }
  clone() {
    return new MyClass(this.toPayload());
  }
}

This component receives an instance of MyClass, clones it and passes it to the Modification component for modification. However, after resetting the object, the Modification component does not update with the new values. Why is this happening? Any missing steps or Vue mechanisms I'm unaware of?

Note: Found a solution here to force updates on the Modification component.

Appreciate the help!

UPDATE: Adding a computed property showing log information each time newObject is updated. Also, adding

<span> {{ newObject.a }} </span>
in the template updates accordingly.

These tests confirm that the variable is reactive.

UPDATE 2:

The Modification component currently contains 2 Input components.

<template>
  <v-card-text>
    <ModifyA v-model="object.a" @input="handleInput" />
    <ModifyB v-model="object.b" @input="handleInput" />
  </v-card-text>
</template>
<script>
import { MyClass } from "classes";
import ModifyA from "...";
import ModifyB from "...";
export default {
  name: "ShiftFormFields",
  components: { ModifyA, ModifyB },
  props: {
    value: {
      type: MyClass,
      required: true
    }
  },
  data() {
    return { object: this.value };
  },
  methods: {
    handleInput() {
      this.$emit("input", this.object);
    }
  }
};
</script>

If ModifyA Input is added directly instead of within the Modification component like this:

<template>
  <v-card>
    <ModifyA v-model="newObject.a"></Modification>
    <OtherComponent @close="resetObject"></OtherComponent>
  </v-card>
</template>

The resetObject function also resets the value shown in the ModifyA component.

Answer №1

The way your MyClass clones the object was not demonstrated.

There may be a lack of reactivity in that process.

To check, you can use console.log() to see the console output.

If it is reactive, it should display something like MyClass {__ob__: Observer}

You might need to utilize this.$set('propName', value) to solve the issue.

For more information, refer to the documentation: https://v2.vuejs.org/v2/api/#vm-set

This method adds a property to a reactive object, ensuring that the new property remains reactive and triggers view updates. It is essential to use this when adding new properties to reactive objects since Vue cannot detect regular property additions (e.g. this.myObject.newProperty = 'hi').

Answer №2

It seems like there may be a mistake in your message, or perhaps the error is also present in your code and causing the issue.

You mentioned that you're linking "newObject" to the Adjustment component, but the parent component actually contains the property "newObjekt."

Could this be the root of the problem you're experiencing?

Answer №3

I came across the solution in this specific answer.

After modifying my original post to include the definition of the Modification component

<template>
  <v-card-text>
    <ModifyA v-model="object.a" @input="handleInput" />
    <ModifyB v-model="object.b" @input="handleInput" />
  </v-card-text>
</template>
<script>
import ModifyA from "...";
import ModifyB from "...";
export default {
  name: "ShiftFormFields",
  components: { ModifyA, ModifyB },
  props: {
    value: {
      type: MyClass,
      required: true
    }
  },
  data() {
    return { object: this.value };
  },
  methods: {
    handleInput() {
      this.$emit("input", this.object);
    }
  }
};
</script>

it highlights the issue with why the Fields ModifyA and ModifyB fail to update when the value changes in the parent component.

Based on the provided definition, the variable object is only assigned the initial value of value upon Component initialization. This results in object not reacting to changes in value.

To address this, one can implement the method outlined in the aforementioned answer:

<template>
  <v-card-text>
    <ModifyA v-model="object.a" />
    <ModifyB v-model="object.b" />
  </v-card-text>
</template>
<script>
import { Shift } from "classes";
import ModifyA from "...";
import ModifyB from "...";
export default {
  name: "ShiftFormFields",
  components: { ModifyA, ModifyB },
  props: {
    value: {
      type: MyClass,
      required: true
    }
  },
  data() {
    return { object: this.value };
  },
  watch: {
    value(val) {
      this.object = val;
    },
    object(value) {
      this.$emit("input", value);
    }
  }
};
</script>

By utilizing a watcher, the object variable is now updated whenever the value changes within the parent component.

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

The issue of Next.js redux useSelector causing HTML inconsistency

Currently, I am utilizing Next.js for the development of a React application. In order to manage the state, I have integrated redux along with redux-toolkit. A peculiar error has surfaced in the console with the message: Warning: Did not expect server H ...

Importing an external JSON file into a ChartJs chart

As a newcomer to using libraries for drawing charts in JavaScript, I recently started playing around with Chartjs. However, I'm having trouble figuring out how to use getJson or any other method to load my json object and update the labels and data. I ...

Rejuvenating your HTML content with AJAX over time

My HTML page contains links to charts that refresh every time the page is reloaded. A friend mentioned that AJAX can automatically refresh the chart at specified intervals without reloading the entire HTML page. I would appreciate any help with the HTML ...

Selecting items with checkboxes in a Bootstrap dropdown menu

As I work on customizing a bootstrap dropdown with checkboxes, my goal is to have the label name written on the input dropdown in between ';' whenever a checkbox from the dropdown is selected. This will create a similar result as shown in the upl ...

Loading React Components dynamically depending on user input

Looking to dynamically render different Components based on checkbox selections without unnecessary component imports. Using an Array with Component names (using numbers for example) to import each component based on the array values. Considered the foll ...

Discover how ReactJS can dynamically display or hide div elements based on specific conditions being met within JSON data

How do I show or hide a div based on a condition in React, using data from a JSON array? I have implemented the code below, but changing the value of isPassed={resultPass.pass} to isPassed={resultPass.failed} still displays the result as pass. I came acro ...

One way to dynamically hide certain fields based on the value of another field is by utilizing AngularJS, Razor, and C# in

Need assistance with AngularJS and Razor. I am a beginner in these technologies and need some help with the following code snippet: <div ng-app=""> <p>Input page number to filter: <input type="text" ng-model="pageNumber"></p> ...

Why does my body feel devoid whenever I submit a post request from the React JS frontend?

Angular js: export const addUser=( username, email )=> { return (dispatch) => { fetch("http://yourdomain.com/addUser", { method: "post", credentials: 'same-origin', mode: 'no-cors', ...

The issue arises when the logout component fails to render even after the user has been authenticated. This problem resembles the one discussed in the React Router

While attempting to run the react-router docs example on the browser, I encountered an issue with the AuthButton component. The problem arises when the isAuthenticated value changes to true but the signOut button fails to display. import React from ' ...

When clicking on HTML input fields, they do not receive focus

I am facing a puzzling issue where I am unable to access the input fields and textareas on my HTML form. The JS, HTML, and CSS files are too large for me to share here. Could someone provide guidance on what steps to take when troubleshooting this unusual ...

Enhancing jquery datatable functionality with data-* attributes

I successfully added an id to each row of my data table using the rowId property, as outlined in the documentation. $('#myTable').DataTable( { ajax: '/api/staff', rowId: 'staffId' } ); Now I am wondering how I can ad ...

rearrange results in ng-repeat based on specified array in AngularJS

Currently delving into Angularjs and have a quick query: I recently received an array from a user which looks like this: userPreferences = [7,5,4] Additionally, I am working with an object that uses ng-repeat to showcase various news items. The object s ...

Customized settings saved in local storage using JavaScript

Here is the script I am currently using for my app: <script> if (localStorage.getItem("0") === null) { //do nothing } else if(localStorage.getItem("1")===null{ } else if(localStorage.getItem("2")===null{ } else if(localStorage.getItem("3")===null ...

Retrieve and utilize the dynamically produced values from the application's app.js in a script that is accessed using

In my Express.js Node web app, I generate a string in app.js during initialization: // app.js var mongourl = /* generated based on process.env.VCAP_SERVICES constant */; There is a script that I import into app.js using require(): // app.js var db = req ...

Is it possible to extract the value displayed on a Typography component in Material UI and store it in a state variable?

I'm currently facing an issue with mapping a data array onto material-ui Typography elements. Here's the code snippet: { array.map((item, id)=> <Typography key={id} value={item.name} />) } While this code successfully displays the val ...

What is the best way to smoothly scroll to another page using a specific id?

My website consists of multiple pages and I am looking for a code that will allow for smooth scrolling navigation to another page when loading on a specific id or section. For example, in the navbar I have multiple pages with links. When clicking on a lin ...

Find the two numbers within a specific range in an array using jQuery

I have two arrays and I need to check for any duplicate ranges. How can I achieve this? let startingArray = ['1', '6.1', '10', '31','6.2',3]; let endingArray = ['2', '9.9', '30&ap ...

Exploring the power of jQuery and Ajax together

Today seems to be one of those days where even the simplest tasks become a challenge. I'm sorry if this question has been asked before, but I'm struggling with a basic issue. I want to dynamically update text on a website using a text file, and w ...

Developing a fresh feature in Angular.js for transmitting my localstorage model information to a bus?

As a beginner in Angular Js, I have mastered the basics and am now working on storing user input values to localstorage using a form. Although this part is working fine, I need assistance in creating a new service to communicate with my colleague's . ...

I encounter an issue with the ng-repeat in my code

It appears that the rendering is not working properly. http://plnkr.co/edit/IoymnpSUtsleH1pXgwFj app.controller('MainCtrl', function($scope) { $scope.lists = [ {"name": "apple"}, { "name": "banana"}, {"name" :"carrot"} ]; }); ...