Retrieving Vue data from parent components in a nested getter/setter context

<template>
  <div id="app">
    {{ foo.bar }}
    <button @click="meaning++">click</button> <!--not reactive-->
    <button @click="foo.bar++">click2</button>
  </div>
</template>

<script lang="ts">
import { Component, Vue } from "vue-property-decorator";

@Component
export default class App extends Vue {
  private meaning = 42;

  private foo = {
    that:this,
    get bar() {
      return this.that.meaning;
    },
    set bar(value) {
      this.that.meaning = value;
    },
  };

  created() {
    console.log(this); // VueComponent {}
    console.log(this.foo.that); // App {}
    console.log(this === this.foo.that); // false
  }
}
</script>

I need to establish a connection between foo.bar and meaning, which is a top-level data field. The initial workaround involves saving this (the Vue option instance) in that. However, the issue arises when this refers to the VueComponent instance instead of this.foo.that.meaning during runtime.

Another challenge is that the above code snippet causes vue-devtools to malfunction within Chrome, as it attempts to invoke Object.keys() on instance._data, which is null.

What is the correct method for linking foo.bar to meaning? The logic within those getter and setter functions may be complex.

Answer №1

Update:

After realizing that referencing `this` in the VueComponent can only be done at runtime, I devised a somewhat unconventional workaround:

<template>
  <div id="app">
    {{ foo.bar }} 
    <button @click="meaning++">click</button>  <!-- now reactive! -->
    <button @click="foo.bar++">click2</button>
  </div>
</template>

<script lang="ts">
import { Component, Vue } from "vue-property-decorator";

@Component
export default class App extends Vue {
  private meaning = 42;

  private foo = {
    that: {meaning:42} as any, // initialize with exact same literal value here
    get bar() {
        return this.that.meaning;
    },
    set bar(value) {
      this.that.meaning = value;
    },
  };

  created() {
    this.foo.that = this;
    console.log(this); // VueComponent
    console.log(this.foo.that); // VueComponent
    console.log(this === this.foo.that); // true
  }
}
</script>

Original solution:

If you are encountering a similar issue, I have come to the realization that

it's not feasible to reference external data within inner object data in the Vue configuration instance.

This is because the VueComponent instance can only be accessed at runtime, but setting that:this in the constructor of the Vue config class is necessary before VueComponent instantiation. Therefore, Vue's reactive system won't have an opportunity to resolve the reference in that.

My advice (based on my experience) is simply do not attempt this. Dependencies must always take precedence over dependents, and you should avoid using foo as the namespace for bar.

Elevating bar to the top level is the way to go.

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

NextJS able to execute code on the client side after being called from the server side

I am currently using getStaticProps to retrieve data from the server at build time and pass it to my page component. The following call is made from my page component file: const getStaticProps: GetStaticProps = async (context) => { const pa ...

Obtaining the identifier of a generic type parameter in Typescript

Is there a method in TypeScript to retrieve the name of a generic type parameter? Consider the following method: getName<T>(): string { .... implement using some operator or technique } You can use it like this: class MyClass{ } getName< ...

Issue: Unable to call method "call" as the model "Model" has not been initialized within a Sequelize instance. Kindly ensure that "Model" is added to a Sequelize instance before attempting to use the "call" method

Author.ts import {Table, Model, Column, DataType} from 'sequelize-typescript' @Table export class Author extends Model<Author> { constructor(){ super(); } @Column(DataType.STRING) fname: string @Column(DataType.STRING) lname: strin ...

implementing dynamic visibility with ngIf directive in Angular

header.component.html <nav class="navbar navbar-default"> <div class="container-fluid"> <div class="navbar-header"> <a href="#" class="navbar-brand">Recipe Book</a> </div> <div class="collapse na ...

Controller method remains inaccessible despite multiple attempts with Javascript ajax Get call

I've tried numerous solutions for this issue, but I'm still unable to make it work. My goal is to invoke a controller method that accepts a parameter and returns a string based on that parameter. Despite using an ajax GET request, the outcome is ...

Any property modified by an event handler will consistently appear in its original form

Every second, a simple function is called using setInterval, with the goal of determining mouse or keyboard activity. The variable that tracks the activity is updated, but it always remains set to 0 despite the fact that console.log statements are being e ...

Revamp responsiveness in bootstrap 3 for printing with @media queries

My goal is to disable the responsive features of bootstrap when the event javascript:print() is triggered. This way, I want my webpage to maintain the column grid layout that I have defined, regardless of screen size. One solution suggested in this answer ...

"Step-by-Step Guide: Activating Tab Functionality in J

I'm facing an issue here - I've been attempting to log the event's key code and I keep getting key number (9). I believe my script isn't disabling event.keyCode properly, hence the key function remains active. What changes should I make ...

Having trouble invoking an established route within a different route in an Express JS project

While working with an Express JS application connected to a mySQL database, I encountered an issue when trying to fetch data from a pre-defined route/query: // customers.model.js CUSTOMERS.getAll = (result) => { let query = "SELECT * FROM custo ...

Guidelines on how to retrieve information from an AJAX request in PHP

I am in the process of developing an application that involves calling a JS function in PHP like this: $data = "<script>JSFunction();</script>"; The JSFunction is defined as follows: function JSFunction(){ $.ajax({ type: 'POST' ...

Exploring Search Functionality with Vue.js 2 and Axios: Implementing API Filtering

I am currently trying to sort through a list of films that I have retrieved using axios. The purpose is to compare them to a search string for a search feature. Everything seems to be working fine, except when I use the computed property, it gives me an er ...

Node 14 introduces a new feature that allows modules to be imported using absolute paths for native ES6 modules

As I develop an app in node version 14.9.0, the need for importing modules arises. To make the process cleaner and more organized, I have configured my ES6 module with "type": "module" in my package.json. My goal is to implement absolut ...

Tips for disentangling code from types in Typescript

Instead of intertwining code and types like the example below: const compar8 : boolean | error = (action: string, n: number) => { switch(action) { case 'greater': return n > 8; case 'less': ...

Retrieving the value of a nested JSON object with a dynamic key

Currently, I am attempting to log a JSON key that is dynamic to the console. However, there is another nested object inside the main object that I also need to access a value from. The key of this nested object contains special characters, so I have been u ...

Is there a way to determine the number of syllables in text as it is being typed?

Working on a React-based web app, I am trying to determine the number of syllables in a textarea as the user types. Encountering errors like "cannot find length of a null" at every turn. Right now, all I want is to utilize console.log() for troubleshooti ...

What is the method for importing the "numeric" library version "^1.2.6" into an Angular project?

I recently added the package "numeric": "^1.2.6" to my project. In addition, I included the types: "@types/numeric": "^1.2.1" When attempting to import this into my Angular application: import * as numeric from &ap ...

Encountering a compilation error while trying to utilize a union type in a function parameter within an

As stated on https://www.typescriptlang.org/docs/handbook/declaration-files/do-s-and-don-ts.html, it is recommended to utilize multiple types for a parameter in a function (refer to the union part) /* OK */ interface Moment { utcOffset(): number; ...

Warning: When VueJs OnMount props is utilized, it might display a message stating, "Expected Object, received Undefined."

This is my current component setup: <template> <Grid :items="items" /> </template> <script setup> import { ref, onMounted } from 'vue' import Grid from '@/components/Grid.vue' import { getData ...

How can we identify if the user is utilizing a text-input control?

Incorporating keyboard shortcuts into my HTML + GWT application is a goal of mine, but I am hesitant about triggering actions when users are typing in a text area or utilizing the keyboard for select menu operations. I am curious if there exists a method ...

Using pg-promise to insert a UUID into the database

I am in the process of setting up a new server and I want each customer to have a unique UUID identifier. My goal is to allow the customers name, parent company, and internal id to be input through a web interface, while the UUID is generated on the server ...