What is the best way to send information to a Vue component so that future changes are automatically displayed?

I am currently working on dynamically updating a Vue JS prop after the view has loaded and the custom has been initialized. In my project, I am building a custom Vue plugin where I use props to pass options, one of which is an object that needs to have its value updated dynamically after the component has loaded. Here is an example:

<div id="app">
  <script>
  var seedData = {
    percent: 50,
    name: 'Smith'
  }
  setInterval(() => {
    seedData = {
      percent: Math.random(),
      name: 'Smith'
    }
  }, 1000)
  </script>
  <offers :parent-data="seedData"></offers>
</div>
Vue.component('offers', {
  template: '<h1>Parent Data: {{ parentData.percent }}</h1>',
  props: {
    parentData: {
      default: () => ({
        percent: 0,
        name: 'John'
      }),
      type: Object
    },
  }
});

// create a new Vue instance and mount it to our div element above with the id of app
var vm = new Vue({
  el: '#app'
});

Initially, the values from offersData are loaded, but the new values set by the setInterval function do not get passed through.

I attempted to add a watcher inside my custom Vue plugin that is loaded through <offers>, but unfortunately, this approach did not work as expected:

watch: {
  parentData: function (newVal) {
    this.parentData = newVal
  }
}

UPDATE

Here is my implementation:

Code Pen -> https://codepen.io/sts-ryan-holton/pen/VwYNzdZ

Answer №1

There are a number of issues with your code

  1. Within <div id="app">, everything is considered by Vue as a template and compiled - refer to the documentation

If neither the render function nor the template option is provided, the in-DOM HTML of the mounting DOM element will be extracted as the template. In this scenario, the Runtime + Compiler build of Vue should be utilized.

Including the <script> tag there is incorrect. Instead, try including the debug build of vue.js rather than the minified production build (vue.min.js) of Vue, which will result in numerous errors (by the way, it's advisable to use the debug build for development purposes as it provides useful errors and warnings)

The fact that it "somehow works" in the production build (i.e., the initial values are displayed on the page) doesn't imply that it's officially supported...

  1. Therefore, the content within <div id="app"> serves as the template for Vue. As mentioned earlier in the comments, all data referenced by the template must be within the context of the Vue instance. It's not feasible to pass a global variable into props. Hence, moving the <script> outside of <div id="app"> won't resolve the issue

[Vue warn]: Property or method "seedData" is not defined on the instance but referenced during render. Ensure that this property is reactive, either in the data option, or for class-based components, by initializing the property.

To address this, you can pass the seedData object into the root Vue instance like so:

       var vm = new Vue({
          el: '#app',
          data: {
            seedData: seedData
          } 
        });

Now that the errors have been resolved, but the changes in data are still not reflected. This issue is not specific to Vue but a fundamental JavaScript concept. Objects are passed by reference in JS. Consider this example:

var a = { name: 'John' }
var b = a
a = { name: 'Smith' }
// b still points to the "John" object

To work around this, avoid replacing the entire object. Instead, modify its properties (be cautious of Vue reactivity caveats)

      setInterval(function() {
          seedData.name = 'John';
          seedData.percent = Math.random();
      }, 1000)

Overall solution:

Vue.component('offers', {
  template: '<h1>{{ parentData.name }}: {{ parentData.percent }}</h1>',
  props: {
    parentData: {
      default: () => ({
        percent: 0,
        name: 'John'
      }),
      type: Object
    },
  }
});

// create a new Vue instance and mount it to our div element above with the id of app
var vm = new Vue({
  el: '#app',
  data: {
    seedData: seedData
  } 
});
<script>
      var seedData = {
        percent: 60,
        name: 'Smith'
      }
      setInterval(function() {
          seedData.name = 'John';
          seedData.percent = Math.random();
      }, 1000)
    </script>
    <div id="app">      
    <offers :parent-data="seedData"></offers>
  </div>
  <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.10/vue.js"></script>

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

I encountered an unexpected obstacle while reloading my Next.js application with animejs. The error message reads: "SyntaxError: Unexpected token 'export'." This unwelcome occurrence took place during the

Encountering an error with animejs when reloading my Next.js app: An unexpected token 'export' is causing a SyntaxError. This issue occurred during the page generation process. The error originates from file:///Users/.../node_modules/animejs/lib ...

The Javascript Node class encountered an error: X has not been defined

I have a class that looks like this: const MongoClient = require("mongodb").MongoClient; const ConnectionDetails = require("./ConnectionDetails").ConnectionDetails; const Recipe = require("./recipe").Recipe; var ObjectId = req ...

Overflow: Scroll vertically and Visible horizontally

I'm struggling with a problem and can't seem to find a solution. https://i.sstatic.net/fw8C9.png My goal is to have the container scroll vertically only, while allowing overflow horizontally to display a dropdown menu. Is this even achievable? ...

Issue encountered during rootScope update

I've encountered an issue with my Angular service that updates the $rootScope. The actual updating process works as intended, but it triggers an error in the console that has me concerned. app.service("scroll", function($rootScope, $window) { this ...

The looping mechanism in Angular is not being updated because of how the $mdDialog from Material Design is being implemented

After reviewing my previous post on Angular loop is not updating, I made a slight modification to the code by incorporating a dialog box for user interaction. The only change in my app.js file was the addition of a $mdDialog box directive. Therefore, the ...

Stopping animation in jQuery function before it starts

After each update, a function is executed: window.ticker.client.updateData = function (data) { try { if (viewModelOrder.selectedInstrument == data.symbol) { viewModelOrder.updatePrice(data.ask.to ...

MongoDB and Node.js encounter unexpected outcomes due to undefined variables

I am trying to retrieve data from my collection called students within the pool database in MongoDB. Despite having a successful connection to the database, when I use console.log(result.lastname), it returns undefined. Below is an excerpt from my server ...

The PUT rest service does not function in AngularJS version 1.0.8

I am facing an issue with my AngularJS application that has a CRUD Rest service. While the Create, Read, and Delete methods are functioning properly, the PUT method is not working. I have searched on Stackoverflow and found similar problems with accepted s ...

Animating SVG while scrolling on a one-page website

Is there a way to incorporate SVG animation scrolling in a single page website? I am inspired by websites like and . The first one stands out to me because the animation is controlled by scrollup and scrolldown actions. I haven't written any of my S ...

What is the simplest way to display an HTTP response in an alert window?

Struggling to display the JSON response using JavaScript's window.alert or alert. As a non-native JS coder, I apologize for my lack of experience. Here are a few attempts I've made based on online examples. My objective is to showcase the JSON r ...

HTMLMediaElement does not have the setSinkId method

I am currently in the process of developing a WebRTC application using Angular, with the goal of managing audio output through the setSinkId() method within HTMLMediaElement. However, when attempting to use this method, I am encountering an error message s ...

Tips for changing the size and color of SVG images in a NextJS application

Looking to customize the color and size of an svg image named "headset.svg". Prior to this, I used next/image: <Image src={'/headset.svg'} alt='logo' width={30} height={30} className='object-contain' /> The s ...

Create a variable called `myUInt8Array` of type `UInt

How can I declare a function parameter of type UInt8Array in TypeScript? import * as fs from "fs"; fs.readFile(fileName, (err: string, data: UInt8Array) => { if (err) { return console.error(err); } ...

What is the best method for saving HTML form data into a Node JS variable?

I am facing an issue with setting the values of HTML form inputs onto my Node JS variables. In the JavaScript code below, I am struggling to assign values to the variables "hostname" and "port," which should then be concatenated to create a new variable ca ...

Accessing state in Vuex modules is crucial for managing and manipulating data effectively

Feeling a bit lost here... I'm utilizing Vuex in my project and have a module called common stored in the file common.js: const initState = { fruits: [] } export default { state: initState, mutations: { SET_FRUITS(state, fruits) { cons ...

The issue of receiving a 500 error when making a POST request in node.js

I have created my own unique REST API that utilizes an NLP API internally. I need to post data on their URL, but unfortunately I am encountering an error that is causing my API to return a 500 error to the frontend. Below is a snippet of my server.js code ...

Managing multiple checkbox selections in React.js

Hello everyone, I'm currently working on trying to assign a function to my "select all" checkbox button to toggle the state when the button is clicked. However, I seem to be encountering an issue. Can anyone lend a hand? Here is my current state: ...

What is the best way to initiate an AJAX GET request from the client side in Node.js/Express?

In my file called shuffleRoute.js, I have the following code: router.get("/shuffle?jokers=false", function (req, res) { cards['a','b','c']; let shuffledCards = _.shuffle(cards); res.status(200).send(shuffledCards) ...

"Using Nightwatch.js to Trigger a Click Event on a Text Link

My goal is to use Nightwatch for testing the login process by clicking on a log in text link. I came across this helpful article: How to click a link using link text in nightwatch.js. The article suggested using the following code: .useXpath() // ever ...

Implementing CSS keyframes when a specified PHP condition is satisfied

I am looking to implement an opening animation on my website that should only play when a user visits the site for the first time. I want to avoid displaying the animation every time the page is reloaded, so it should only run if a cookie indicating the us ...