The issue lies in the constructor not properly updating the property when referencing "this

Apologies for the confusion with the question title, I am still new to using constructors in JavaScript and struggling with how to properly phrase it. Here is the issue I am facing:

I am implementing a Builder pattern (using a constructor) to create an object and assign specific values to it. The code snippet looks like this:

DataBuilder.js

export class DataBuilder {
    static getDefaultData() {
        return new DataBuilder();
    }

    constructor() {
        this.test = 'original';
        this.data = {
            title: `myTitle`,
            meta: [
                    {
                    hid: "og:title",
                    name: "og:title",
                    property: "og:title",
                    content: `Would like some content here with ${this.test} in the middle of a string`,
                    },
               ]
         }
    }

    setTestData(input) {
        this.test = input;
        return this;
    }

    build() {
        return this.data;
    }
}

And this is how I call it from my Vue component:

index.vue

export default {
  head() {
    return DataBuilder.getDefaultData()
      .setTestData("testing123")
      .build();
  },
}

The issue arises when building the object. While this.test gets updated successfully with testing123, the content inside the meta remains unchanged showing content: original. Ideally, the meta/content should have been updated to display content: testing123.

I suspect that the this variable is not reactive or updating within the constructor. I'm unsure of the correct approach to address this. Where should I implement the necessary set function to update all the fields accordingly?

Answer №1

To ensure that the data setting always reflects the most current field values, one approach is to move the data assignment inside the build() method:

export class DataBuilder {
    //...

    build() {
        this.data = {
            title: `myTitle`,
            meta: [
                {
                    hid: 'og:title',
                    name: 'og:title',
                    property: 'og:title',
                    content: `Would like some content here with ${this.test} in the middle of a string`,
                },
            ]
        };
        return this.data;
    }
}

class DataBuilder {
    static getDefaultData() {
        return new DataBuilder();
    }

    constructor() {
        this.test = 'original';
    }

    setTestData(input) {
        this.test = input;
        return this;
    }

    build() {
        this.data = {
            title: `myTitle`,
            meta: [
                {
                    hid: 'og:title',
                    name: 'og:title',
                    property: 'og:title',
                    content: `Would like some content here with ${this.test} in the middle of a string`,
                },
            ]
        };
        return this.data;
    }
}

const data = DataBuilder.getDefaultData().setTestData('foo').setTestData('bar').build()
console.log(data)

Answer №2

content: `Include some text here with ${this.test}`

This content is only evaluated when it is assigned, not when accessed or read.

If you want the evaluation to happen on access, you should define the property as an accessor property with a getter:

this.data = {
        title: "myTitle",
        meta: [
                {
                    hid: "og:title",
                    name: "og:title",
                    property: "og:title",
                },
           ]
     }
this.data.meta.forEach(obj => 
    Object.defineProperty(
        obj, 
        "content", 
        { 
            get: function() { 
                return `Include some text here with ${this.test} in the middle of a sentence` 
            }, 
            enumerable: true 
        }
    )
);

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

A new marker has been created on the Ajax Google Map, however, the old marker is still displaying as

Hey, I'm currently working on retrieving marker latitudes and longitudes using Ajax. I am receiving Ajax data every second and successfully creating markers within a specific radius. However, I'm running into an issue with updating marker positio ...

Can you explain why there is a discrepancy in the canvas coloration?

When I try to draw a line on my canvas with color "#ca5100", the actual color that appears is "#e4a77f". Why does this difference occur and how can I ensure that the correct color is set? var ctx = document.getElementById("mycanva").getContext("2d"); ct ...

Adjust the focus on the Angular JS input element

I have a student database with an input text element. When the page loads, I want a student to be highlighted with the input text focused. I created a dynamic class that will set the focus if it is true. If I apply it to a static class, it works fine. How ...

Various perspectives within a state

I am facing an issue with my articledetail state when navigating to it: $state.go('articledetail', { 'article': article.itemNumber }); Within the articleDetail.html file, I want to display all subviews simultaneously: <div cla ...

Distinguish between closing a browser tab and refreshing it to identify various instances of the application

How do you differentiate between browser tab close and refresh functionality? Currently, window refresh and close events do not have separate events. My requirement is to check whether the user is already logged in on any tabs, so that I can prevent th ...

Supertest and Jest do not allow for sending JSON payloads between requests

Below is the test function I have written: describe("Test to Create a Problem", () => { describe("Create a problem with valid input data", () => { it("Should successfully create a problem", async () => { const ProblemData = { ...

"Ionic offers a seamless integration of both side menu and tabs for enhanced navigation

I am working on implementing a sidemenu and tabs on the same screen in my Ionic app project. Currently, it is almost working, but I need the bottom tabs to be visible at all times while also being able to navigate to other views from the sidemenu without ...

Initiating a GET request to retrieve the file generated by the server

I am currently delving into the Mean stack and have encountered a challenge with downloading a file from my server-side application using the Angular front end. Despite successfully generating the file on the back end, clicking the download button on the f ...

Troubleshooting issue: Dropdown menu malfunctioning after using replaceWith() and appendTo()

I could really use some assistance. Admittedly, my knowledge of php, js, jquery, and similar languages is limited. I am currently working on a small web application where users fill out a form with specific requests, the data is then stored in a database, ...

Is there a way to programmatically prevent the back button from functioning if the previous route pathname in React was 'Login'?

When it comes to navigating back on previous pages, the traditional back button is typically used instead of relying solely on the navigation bar. However, I am currently looking to disable this feature specifically when the next previous route in line is ...

What could be causing the '!!disabled!!' message to appear in a TextField within ipyvuetify?

After inserting some text into the v_document, I click on v_btn_document but it shows !!disabled!!. Why is this happening? import ipyvuetify as vue def on_click_get_numbers(widget, event, data): print(v_document.v_model) # Why am I getting !!disable ...

Looking for assistance with submitting a form?

Looking for assistance with a JavaScript hack. Since this morning, I've been trying to figure out a simple hack that would enable me to submit a form multiple times. Take a look at this image. https://i.sstatic.net/GffW1.png It's a basic form ...

Using Jquery to toggle columns based on their index and custom attribute

My table has two rows in the header: the first row with colspan and the second row containing headers. You can see an image below for reference. https://i.sstatic.net/qwSBL.png With a jQuery function, I extract all the table cell values from the second h ...

Provide the flow type parameter to the React component

Is there a way to generate flow type in an external component without duplicating types when using it within another component? For instance: import {ExternalComponent} from '@npm-component/another-component'; type CurrentComponentType = {| d ...

The code functions properly when run locally, however, it encounters issues when deployed

When testing the following lambda code locally using Alex-app-server, everything works perfectly fine. However, when I publish it and test on AWS Lambda, it gets stuck within the else statement. It prints the console log 'OUT PUBLISH' but doesn&a ...

Revamp the Like Feature

Currently, I'm utilizing Lumen, Vuejs, and Axios for a project. In this setup, signed-in users have the ability to post content, while others can like and comment on those posts. My main goal is to visibly indicate when someone has liked a particular ...

Vue Js is failing to display an image retrieved from the assets folder

Despite searching for solutions, I have been unable to resolve my issue. My Json server contains the following data: file.json { "post": [ { "id": "1", "title": "Title" ...

Error message: React Native encountered a prop type failure when an invalid prop of type array was passed to the Overlay component

I am brand new to React Native and encountering an error message when opening a specific component. Although it doesn't hinder navigation, I would like to resolve this issue. I suspect it could be related to a syntax or typo error, but pinpointing the ...

Using Vue Js to conditionally disable updates to v-model

I need to update the v-model of the dropdown if it becomes disabled based on a condition. Specifically, I want to set my ir.IR_SectionId back to 0 when the select box is disabled. <select v-model="ir.IR_SectionId" v-default-value:ir.IR_SectionId="0" ...

Loading and Manipulating OBJ Models with THREE.js

I am experiencing an issue with accessing an object outside of the event boundaries. When I put the object in an array and check out that array, it appears to be empty; however, within the event scope, it is full. I am seeking a solution for how to acces ...