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

Is there a way to identify and count duplicate data-items within an array, and then showcase this information using a react view?

If we have an array like this: [{id: 1, name: "chocolate bar"}, {id:2, name: "Gummy worms"}, {id:3, name:"chocolate bar"}] Is there a way to show on the dom that we have "2 chocolate bars and 1 Gummy Worms"? ...

Create a PHP form that includes text and image inputs with the help of AdminLTE and integrates DropZone.js

I have been working with a template from adminLTE and you can check it out at the following link: . At this point, I am trying to upload images first and then use the image names as input text elements in my main form for submission. However, I have encou ...

Attempting to utilize a Python web scraping tool to extract content from a webpage that undergoes regular text updates

I must admit that I am a complete beginner who is feeling lost and unsure of what to do. My goal is to extract 4 pairs of numbers from a webpage using a web scraper. These numbers change when modified on a different page, but I'm unable to pull the d ...

Encountering an issue in Laravel 8 JetStream: Mix file '/css/app.css' cannot be found when running npm run prod

I have a Laravel 8 application set up with Jetstream, Inertia Js, and VueJs 3. When I execute: npm run prod An error occurs: Exception Unable to find Mix file: /css/app.css. (View: /var/www/html/mysite/resources/views/app.blade.php) http://subdomain.mysi ...

My goal is to develop a custom forEach function that retrieves a substring from each element in an array

I have a file containing image names like: sciFi.png, posed.png, birdA.png, dolphin.png, horse.png, shake.png, loft.png, basement.png, avenger.png, friend.png In my JavaScript document, I am trying to read this file and convert it into an array. Then, I w ...

Unable to display content within .vue file

My Index.vue file includes the following code, however, it is not displaying properly. <div> test </div> <script> export default { // } </script> ...

jQuery does not change the scroll position of elements

I'm looking to implement a feature on my website where certain points act as "magnets" and when the user is near one of these points, the window automatically scrolls to the top. I found a jQuery plugin that does something similar which you can check ...

Passing data between parent and child components within an Angular application using mat tab navigation

I am currently working on a project, which can be found at this link. Current Progress: I have implemented a mat tab group with tabs inside the app-component. When a tab is clicked, a specific component is loaded. Initially, most of the data is loaded in ...

I'm having trouble getting my object to display using ng-repeat in Angular. Can anyone help me understand what I'm missing?

My goal was to add an object to an array upon clicking an event, which I successfully achieved. However, the objects are not displaying in the ng-repeat as ordered. Can you help me figure out what's missing? angular.module('app', []); an ...

Click the "Add to Cart" button to make a purchase

Recently, I've been working on modeling an add to cart feature using jQuery. However, I have encountered a small issue that I'm trying to troubleshoot. When I click the mybtn button, the model displays and functions correctly, but there seems to ...

Unlock the full potential of knockout.js by mastering how to leverage templates recursively

Given the following model and view model for nested categories: function Category(id, name) { var self = this; self.Id = ko.observable(id || '00000000-0000-0000-0000-000000000000'); self.Name = ko.observable(name); self.children ...

Leverage the power of Angular and Node.js to dynamically generate and configure a new subdomain on an

Currently, I am tackling a project that involves generating sub domains dynamically based on the prefixes entered by users on my website. While everything is functioning properly on my localhost using diet.js and express-subdomain, errors are being encount ...

Exploring Ngu-Carousel in Angular 7: Importing JSON data for a dynamic display

After attempting to import data from JSON and display it using ngu-carousel, I encountered an error. The error shows "length of undefined" Subsequently, when I try to click on the previous/next button, another error appears. This error states "innerHTML ...

What's the best way to adjust the width of the <Input> component in Reactstrap?

How can I adjust the width of an input element in Reactstrap to be smaller? I've attempted to set the bsSize to small without success <InputGroup> <Input type="text" name="searchTxt" value={props.searchText ...

What is the reason behind the effectiveness of this prime number verifier?

Take a look at this code snippet that effectively checks whether a number is prime: var num = parseInt(prompt("Enter a number:")); var result = "Prime"; for (var i = 2; i < num; i++) { if (num % i === 0) { result = "Not Prime"; break; } } ...

No instances are returned by Processing.instances

I am experiencing an issue with a webpage that is running 2 processing sketches. I came across a suggestion to call Processing.instances[0].exit() in response to a question on dynamically unloading a Processing JS sketch from canvas. However, when I attem ...

Updating line connections between objects in Three.js while rendering

I am working with a three.js canvas that contains circles moving independently. Initially, these circles are connected by a single line that follows the same geometry as their positions. However, I am facing difficulty updating the line's geometry wh ...

What is the best way to move between websites or pages without having to reload the current page using a selector?

Have you ever wondered how to create a webpage where users can navigate to other websites or pages without seeing their address, simply by selecting from a drop-down menu? Take a look at this example. Another similar example can be found here. When visit ...

When the menu is selected, I would like for this div to both appear on the screen and slide

I need this div to be visible and move up when a menu item is selected. Can anyone provide a solution for this? Thank you in advance. <html><head> <script type="text/javascript"> <!-- var divobject = null; function init(id){ div ...

Having trouble simulating JavaScript Math.random in Jest?

Math.random() seems to always return random values instead of the mocked ones. script.test.js jest.spyOn(global.Math, "random").mockReturnValue(0.123456789); const html = fs.readFileSync(path.resolve(__dirname, "./script.html"), " ...