'Stuck at progressively migrate my website to Vue.js

I chose Vue.js over React and Angular, because it felt much more easier to migrate my existing website (old technologies, ASP.NET Razor Pages inside Visual Studio and no npm) to new technologies.

Everything went great. I changed small portions of my website into Vue applications. For example:

  1. Mini cart viewer
  2. Comment form
  3. Rating
  4. Add to cart button
  5. Dynamic forms

However, now that I want to show a dynamic form inside a modal dialog, things don't work.

The point is, modal dialog is a Vue application, and the dynamic form is also another Vue application. So, basically what I do is to load a Vue application inside another Vue application.

Here's my code for modal:

var modalAppJson = {
    data() {
        return {
            isShown: false
        }
    },
    methods: {
        show: function (data) {
            var _this = this;
            _this.isShown = true;

        },
        hide: function () {
            var _this = this;
            _this.isShown = false;
        }
    }
};
var modalApp = Vue.createApp(modalAppJson);
modalApp.config.globalProperties.app = app;
modalApp.mount('.modalInstance');

And here's my code for dynamic form (Vue.js inside Razor Pages):

formApp = {
    data() {
        return {
            form: {
            },
            fields: []
        }
    },
    methods: {
        addField(key, value, isValid) {
            var field;
            for (var i = 0; i < this.fields.length; i++) {
                if (this.fields[i].key === key) {
                    field = this.fields[i];
                }
            }
            if (!field) {
                field = { key: key, value: value, isValid: isValid };
                this.fields.push(field);
            }
            field.value = value;
            field.isValid = isValid;
        },
        removeField: function () {

        },
        send() {
            var form = $('#@(Model.Key)Form');
            var loader = $('#@Model.LoaderKey');
            var results = $('#@Model.ResultsKey');
            var submitButton = $('#[email protected]');
            submitButton.hide();
            loader.show();
            results.text('');
            app.postJson('action=SaveForm&[email protected]', JSON.parse(JSON.stringify(this.form)), function (data) {
                submitButton.show();
                loader.hide();
                results.text('Form is saved successfully');
                results.addClass('success');
                form[0].reset();
            }, function (error) {
                submitButton.show();
                loader.hide();
                results.text(error);
                results.addClass('error');
            });
        }
    },
    computed: {
        isValid: function () {
            var result = true;
            for (var i = 0; i < this.fields.length; i++) {
                if (this.fields[i].isValid === false) {
                    result = false;
                    break;
                }
            }
            return result;
        }
    }
};
Vue.createApp(formApp).mount('#@(Model.Key)Form');

And here's an example of HTML for these two apps:

<div class="modalInstance">
    <div>
        <a href="javascript:void(0);" @@click="isShown = true">Purchase</a>
    </div>
    <Transition>
        <div v-if="isShown">
            <form novalidate id="@(Model.FormKey)Form" class="formInstance">
                <h1 class="title">@Html.Raw(Model.DatabaseForm.Title)</h1>
                <h3 class="shortDescription">@Html.Raw(Model.DatabaseForm.ShortDescription)</h3>

                @if (hasFieldsRenderer)
                {
                    <partial name="/Pages/Form/@(pascalizedKey)FieldsRenderer.cshtml" model='@Model.Fields' />
                }
                else
                {
                    foreach (var field in Model.Fields)
                    {
                        <partial name="/Pages/Fields/@(field.RelatedItems.TypeKey).cshtml" model='field' />
                    }
                }
                <div class="actions">
                    <partial name="@Actions.Save" model='new ActionParameters { Classes="submit button", FormKey=Model.FormKey, Text="Save" }' />
                    <span id="@(Model.FormKey)Loader" style="display: none;">Saving...</span>
                    <span id="@(Model.FormKey)Result"></span>
                </div>
            </form>
        </div>
    </Transition>
</div>

The top-level <div> is controlled by the modal Vue application, and the <form> element is controlled by the dynamic form Vue application.

However I see this error when I open the dialog:

[Vue warn]: Property "form" was accessed during render but is not defined on instance. Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'Name')

This works if I show the form in the page and not in a modal. But breaks when I put it inside modal.

What can I do to solve this?



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source