How to retrieve props within a data function of a child Vue component?

Could you please help me understand why the level: this.globalForm.level in the child component is not updating with the props from the input selector in the parent component?

Parent Component:

<template>
  <div>
    <div class="form-container">
      <select class="form-control" v-model="level">
        <option v-for="level in options" v-bind:key="level">{{ level }}</option>
      </select>
      <button @click="submit()">Create</button>
    </div>
    <child v-bind:globalForm="globalForm"/>
  </div>
</template>

    <script>
inputFiled;
export default {
  data() {
    return {
      level: "",
      globalForm: {
        level: ""
      },
      options: ["level1", "level2", "level3"]
    };
  },
  components: {
    child
  },
  methods: {
    submit() {
      this.globalForm.level = this.level;
    }
  },
  watch: {
    level() {
      this.globalForm.level = this.level;
    }
  }
};
</script>

Child Component:

<template>
  <div class="form-container">
      <option v-for="level in options" v-bind:key="level">{{ level }}</option>
  </div>
</template>

<script>
export default {
  props: { globalForm: Object },
  data() {
    return {
      options: ["level1","level2","level3",],
      level: this.globalForm.level //I'm trying to update this but it's not working as expected
    };
  }
};
</script>

Answer №1

Summary

level needs to be a computed property within the child component in order to properly detect changes in the prop. By setting level in the data function, updates to the prop fail to reflect in level.

Here is a simplified example of how you can achieve what you are looking for.

Vue.config.productionTip = false;
Vue.component('parent', {
  template: `
  <div class="parent">
    <b>PARENT</b>
    <div class="form-container">
      <select class="form-control" v-model="level">
        <option v-for="level in options" v-bind:key="level">{{ level }}</option>
      </select>
      <button @click="submit()">Create</button>
    </div>
    <child v-bind:globalForm="globalForm"/>
  </div>
  `,
  data: () => ({
    level: "",
    globalForm: {
      level: ""
    },
    options: ["level1", "level2", "level3"]
  }),
  methods: {
    submit() {
      this.globalForm.level = this.level;
    }
  }
});

Vue.component('child', {
  template: `
  <div class="form-container child">
      <p><b>Child</b></p>
      Level: {{ level }}
  </div>
  `,
  props: {
    globalForm: Object
  },
  computed: {
    level() {
      return  this.globalForm.level;
    }
  }
});

new Vue({
  el: "#app"
})
.parent {
  background-color: darkgray;
  padding: .5em;
  border: solid 1px black;
}
.child {
  background-color: lightgray;
  padding: .5em;
  border: solid 1px black;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
  <parent></parent>
</div>

Detailed Explanation

There are some mistakes in your code that I will address below.

In your child component

During initialization of your component, this is not accessible within the data function, causing this.globalForm to be undefined and an error to be thrown in the console.

data() {
    return {
      options: ["level1", "level2", "level3"], // appears duplicated from parent
      level: this.globalForm.level // triggers error
    };
 }

To resolve this issue, you can obtain the vm context from the data function parameters, but this is not the ideal solution for your problem.

data(vm) { // note vm
    return {
      level: vm.globalForm.level // note vm
    };
 }

The main problem lies in level: this.globalForm.level only running once during initialization of the component, resulting in level being undefined. Any subsequent changes to the globalForm prop do not update level due to its initial assignment and loss of reference when data returns a new object.

To overcome this issue, it is recommended to convert level into a computed property, enabling detection of prop changes and accurate value retrieval. Refer to the provided code snippet above.

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 attach an event listener to a span that was inserted using DTColumnBuilder?

I am attempting to include an onclick event for a span element that is generated by DTColumnBuilder. DTColumnBuilder .newColumn('Invoice') .withTitle('<span class="li-table-head ...

What is the best way to automatically show scrollbars when a page loads using JavaScript?

How can I make the vertical scrollbar appear as soon as the page loads using javascript? I am currently using a jquery slide toggle animation that causes the vertical scrollbar to show up because it makes the page longer. However, when the scrollbar appear ...

Experiencing trouble with calculating the total value of an array of objects due to NaN errors

I've been working on developing this web application in VUE.js, but I'm facing an issue with a specific function where I am attempting to sum the values of each object within an array. This is resulting in a NaN (Not a Number) error. Let's t ...

Multiple conditions in TypeScript resulting in a function output

I am working on developing a function that can return different types based on its parameters. Similar to the function below, but I want it to be more streamlined and efficient (using generics without union types as results) type ResultType = { get: Get ...

Sending a parameter from a click event to a function

Struggling with a jQuery and AJAX issue all night. I am new to both and trying to implement something similar to this example. I have an edit button with the ID stored in a data-ID attribute. Here's an example of what my button looks like: <butto ...

Display a Bootstrap modal upon clicking the button to fetch modal information through an Axios response

Here is what I am looking for: 1. When the user clicks the button, a method should be executed to retrieve the Bootstrap modal from the API and then show it to the user. Note: Initially, the modal HTML should not be in the DOM; it will be created on button ...

Grab the webpage's URL by collecting the link from the src attribute of the script tag using XSLT

Can XSLT be used to extract a URL link specified within the src attribute of a script tag in an HTML file? Here is an example of the HTML file: <HTML> <BODY> <SCRIPT language="javascript" src="http://myspace.com" type="text/javascript"> ...

I wonder where this design is originating from

After exploring several of the suggested questions that appeared while typing, I was unable to find a solution to my issue. Currently, I am utilizing Uikit V2 and I have implemented a div with the Sticky component as shown below: <div class="uk-st ...

What is the best way to bring the global stylesheet into a Vue component?

Embarking on my first VueJS project, I decided to create a global stylesheet to maintain consistent styles across different components. After installing the SCSS loader and setting up my stylesheets, I encountered an issue. $mainFont: 'PoppinsRegular, ...

Please optimize this method to decrease its Cognitive Complexity from 21 to the maximum allowed limit of 15. What are some strategies for refactoring and simplifying the

How can I simplify this code to reduce its complexity? Sonarqube is flagging the error---> Refactor this method to reduce its Cognitive Complexity from 21 to the allowed 15. this.deviceDetails = this.data && {...this.data.deviceInfo} || {}; if (th ...

manipulating the position of a slider thumb on an input slider with just vanilla javascript

<td> <div id="fpscount" style="margin-left: 70px; margin-top: -4px; position:absolute;">15</div> <input type="range" name="FPS" min="1" max="60" value="15" id="FPS" class="Slide" onchange="window.status=this.value; Update(this.valu ...

Issues with form validation in Angular reactive forms are causing problems

I recently created a complex reactive form by following the guidelines from this source on how to handle validation in Angular 9. After posting my code in StackBlitz, I ended up with three links: EDITOR URL APP URL EMBED URL If these links are not worki ...

The error "Syntax Error: Unexpected token <" is occurring in a specific environment for jQuery UI, while it is not present in another environment

I recently implemented a basic autocomplete feature on a CakePHP form using jQuery. Below is the snippet of jQuery code used: <script> $(function() { var availableTags = [<?=$suppliers?>]; $( "#MsrSupplier" ).autocomplete({ source: av ...

Extract data from a URL using PHP and JavaScript technologies

Upon receiving a json data from a URL, specifically through celery's flower plugin, the following sample is obtained: { "celery@s1": { "scheduled": [], "stats": { "clock": "2535550", "pid": 26002, "broker": { "tran ...

Vue2Editor not displaying updated content following data retrieval from axios call

I've encountered an issue with my Vue component that uses Vue2Editor. Everything was working great until I tried to update the content using data from an async function. To troubleshoot, I tested updating text in a simple div. Here's a snippet ...

Guide to Appending "Z" to a Date String Using Moment.js in JavaScript and Node.js

I am struggling to format my date to include the "Z" letter at the end. Despite numerous attempts, I have been unsuccessful. The desired format is "YYYY-MM-DDT00:00:00.000Z," but currently it does not include the Z How can I add the Z using moment? It&ap ...

Encountering issues with a variable in Vue returning as undefined

I am attempting to extract all the values associated with an object. My challenge lies in utilizing a variable filter to access specific parts of the object. Here is the code snippet I have: getCategoryData(slug){ console.log(this.categories.products. ...

Error: Discord API experienced an Invalid Form Body error

I've tried multiple approaches, but I'm still unable to resolve the issue with this code. Any assistance would be greatly appreciated. CODE: client.on("messageCreate", async message => { if (message.author.bot || !message.guild) return; if (m ...

Navigating through a list of elements in WebdriverIO with the help of JavaScript

How can I extract the content of each row in a grid with a varying number of rows? I specifically need to access the texts "This can’t be a single letter." and "Enter the last name of the contact person." I attempted: var text = $('#topErrorList&a ...

Is submitting data through ajax giving you trouble?

As a beginner in PHP with no knowledge of Javascript, I have been relying on tutorials to complete my JS tasks. Despite trying various solutions from StackOverflow, I have yet to achieve success! My goal is to update database values by clicking the ' ...