1

I'm working with VueJS library to generate form from a JSON schema, the library work great beside one issue, if I'm loading the JSON directly from the data() I can see the form content perfectly: https://codepen.io/eran-levi/pen/wvGVBGJ

(here is the Schema JSON inside data()):

schema: {
    type: 'object',
    properties: {
        stringProp: {
            type: 'string',
            title: 'I\'m a string',
            description: 'This description is used as a help message.'
        }
    }
}

But, once I'm trying to load it dynamically (I'm loading the data and only then update it), in this case I cant see anything on page, see it here: https://codepen.io/eran-levi/pen/WNwVbGZ

(Here is how I'm trying to update the field):

created() {
    setTimeout(function(){ 
        console.log('Component has been created!');
                    
        this.schema.properties.stringProp = {
            type: 'string',
            title: 'I\'m a string',
            description: 'This description is used as a help message.',
        }                        
    }, 3000); 
}

Can you please explain why I can not update the field dynamically and see it right away?

Thank you!

1
  • Context issue, uses setTimeout(() => {...}, } instead of function () {} Commented Oct 2, 2020 at 22:26

2 Answers 2

1

This is due to the way Vue reactivity works. The properties type, title and description won't be reactive, because they don't exist when the instance is first initialised and it walks the schema object and wraps it to make it reactive to changes. Vue cannot detect property addition or deletion - more on that can be found here.

To make it work, you have a couple of options. You can use Vue.set as below, which will tell Vue there's a new property that needs to be made reactive. That would look like this:

setTimeout(function() {
    this.$set(this.schema.properties, 'stringProp', {
        type: 'string',
        title: 'I\'m a string',
        description: 'This description is used as a help message.',
    });
}.bind(this), 3000);

Alternative, you could change the initial declaration to include the properties you need. That means your initial data would look like this:

data: {
    model,
    options,
    schema: {
        type: 'object',
        properties: {
            stringProp: { type: null, title: null, description: null },
        },
    },
}
Sign up to request clarification or add additional context in comments.

1 Comment

Exactly what I needed, works perfectly, Thank you :)
1

In the second example you forgot comma after created hook and you updating properties instead properties.stringProp like in the first example. In order to update properties.stringProp you need to set it previously to null.

schema: {
    type: "object",
    properties: { stringProp: null },
},

updateScheme() {
    this.schema.properties.stringProp = {
        type: 'string',
        title: 'I\'m a string',
        description: 'This description is used as a help message.',
    }
}

1 Comment

Thank you for your answer, it works for me as well after adding ".bind(this)" to the end, like that: this.schema.properties.stringProp = { type: 'string', title: 'I\'m a string', description: 'This description is used as a help message.' } }.bind(this) Thank you!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.