The reactivity system in Vue does not support string arrays when paired with TypeScript

My UI is designed for users to create 1:n mappings for form fields. The structure of the model is quite straightforward:

export interface IMapping {
    pdfName: string;
    fieldNames: string[];
}

However, I encountered a problem with reactivity when it comes to changes made to the fieldNames. Below is the code snippet for the form that allows users to edit or add a new mapping.

Template:

<form @submit.prevent>
    <div class="field">
        <label for="pdfName">PDF Field Name</label>
        <input type="text" name="pdfName" id="pdfName" required
            v-model="data.pdfName"/>
    </div>
    <div>
        <fieldset v-for="(fieldName, index) in data.fieldNames" :key="index">
            <legend>Form Field</legend>
            <div class="field">
                <label :for="'name_' + index">Name</label>
                <input type="text" name="name" :id="'name_' + index" required
                    v-model="fieldName"/>
            </div>
            <button @click="removeField(index)" class="removeField"><i class="fas fa-minus"></i></button>
        </fieldset>
        <button @click="addField"><i class="fas fa-plus"></i></button>
    </div>
    <div class="buttonrow">
        <button @click="save">Save</button>
        <button @click="cancel">Cancel</button>
    </div>
</form>

TypeScript component

import { Component, Emit, Prop, Vue, Watch } from 'vue-property-decorator';

import { IMapping } from '@/models/IMapping';

@Component
export default class MappingForm extends Vue {

    public data: IMapping | null = null;

    @Prop({type: Object})
    private mapping!: IMapping;

    public created() {
        this.data = {...this.mapping};
    }

    public addField() {
        this.data!.fieldNames.push('');
    }

    public removeField(index: number) {
        this.data!.fieldNames.splice(index, 1);
    }

    @Emit('mapping-changed')
    public save() {
        if (this.mapping === null) {
            return this.data;
        } else {
            Object.assign(this.mapping, this.data);
            return this.mapping;
        }
    }

    @Emit('mapping-unchanged')
    public cancel() {}

}

I store the prop in a local variable to easily revert any changes and only apply them when saved. While it reacts to push and splice operations, the string values are not updated. I attempted using @Watch, but unsure how to implement it in this situation as there's no method to listen to other than user input on my

<input type="text" name="name" :id="'name_' + index" required v-model="fieldName"/>

Answer №1

Give this a shot:

<input type="text" name="name" :id="'name_' + index" required v-model="data.fieldNames[index]"/>

Possibly the issue lies in v-for not properly passing the reference due to it being a primitive type.

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

The scale configuration for scale: x is not valid for creating a time scale chart using chart.js

I am currently utilizing VueJS and attempting to integrate a time scale chart using Chart.js. However, I encountered the following error: Invalid scale configuration for scale: x Below is my configuration : First, I have a component named Chart.vue with ...

Protractor end-to-end tests: extracting chosen menu item from page model function

My website has a navigation menu with different items. I'm using a page model for end-to-end tests. In one of my test specs, I need to call a function from the page model that does the following: Check that only one item in the menu has a specific ...

Is it possible for me to transfer a change to the worldwide namespace from my library?

I am looking to enhance an existing TypeScript type within the global namespace in my library and then expose it for use in other projects. Can this be done? Below is my current code: Promise.ts Promise.prototype.catchExtension = function<T>(this ...

What is the best way to arrange each <v-col> in a vertical stack on mobile devices exclusively?

Is there a way to stack the <v-col> elements vertically on mobile devices only? <v-container> <v-row> <v-col>A</v-col> <v-col>B</v-col> </v-row> <v-row> <v-col>C</v-col> ...

Exploring the integration of Jest with TypeScript

I'm seeking guidance on how to set up TypeScript with Jest. I've scoured numerous resources but haven't found a solution that works for me. Below is my jest.config.js: module.exports = { roots: [ '<rootDir>' ...

Wait to execute until the external script in Vue.js has finished loading

How can I trigger the rendering of a recaptcha after a Vue.js component has mounted? It functions correctly on initial load and reload, but throws an error when navigating away to a different url and using the browser back button. Here is how it's se ...

Is there a built-in feature in npm or yarn that automatically installs @types when they are present in Typescript projects?

Is there a feature in npm or yarn that automatically installs @types/* for packages without their own types, in Typescript projects? For example: //package.json { // ... "installTypes": true } // installing package yarn add ABC <- will install A ...

The latest update of WebStorm in 2016.3 has brought to light an error related to the experimental support for decorators, which may undergo changes in forthcoming

Hello, I recently updated to the latest WebStorm version and encountered this error message: Error:(52, 14) TS1219:Experimental support for decorators is a feature that is subject to change in a future release. Set the 'experimentalDecorators' ...

Am I effectively implementing async await in TypeScript?

I'm not quite sure if I'm using the async/await functionality correctly in my TypeScript and Protractor code. Looking at the code snippet below, the spec uses await to call the page object, which itself is an async/await function. The page object ...

What are the ways to personalize Vant.js?

My website was created with vant.js. I am trying to modify the button background, but for some reason it's not changing. I want to achieve this without using !important. Any suggestions on how I can resolve this issue? ...

Can InstanceType<T> be utilized with an abstract class?

My intention is to enable it to reference implementations rather than the abstract itself, all while exclusively depending on the definitions in the abstract interface. ...

Is your variable being assigned the incorrect type by a Typescript enum?

Within my codebase, I have defined an enum called AlgorithmEnum: export enum AlgorithmEnum { SHA1, SHA256, SHA512 } This enum is utilized as the Algorithm property of a class named Authenticator: export class Authenticator { Type: Type = T ...

Guide to establishing intricate conditions for TypeORM insertion

When attempting to insert data based on a specific condition, such as if shopId = "shopA", I want to include the shopdetail. In order to achieve this, I have implemented the following business logic, which is somewhat complex. Is there a more ef ...

Is the lack of WebStorm IDE support for Vue 3 Composition API a known issue or is there a problem with my configuration?

My experience with Vue 2 was smooth sailing, especially with the impressive WebStorm Plugin - it truly is top-notch and I believe it outperforms VS Code. However, as I delved into multiple Vue 3 projects using the Composition API, I encountered issues wit ...

Creating a tree diagram in Vue

Looking to create a customized tree diagram in my Vue app, similar to the one shown in the image below based on certain data. I want the flexibility to add avatars, buttons, and text as DOM elements within the nodes. Although I came across the Vue.D3.tre ...

Preserving the active menu item in Nuxt and Vue with Element UI when the browser back button is clicked

Hey there, I'm facing an issue with a clicked menu item that shows a 'selected' state by darkening the item for user feedback. The problem arises when the active item gets reset upon pressing the browser back button, even though the route ch ...

Running terminal commands in typescript

Can Typescript be used to run commands similar to JavaScript using the Shelljs Library? ...

Why is my RxJS timer not waiting for the specified time?

I'm diving into the world of RxJS and trying to grasp its concepts. During some testing, I encountered a puzzling issue that has me stumped. Below is the snippet in question : let item = { id: 1, name: 'chair' }; const asyncItem = timer(20 ...

Refreshing Vue components based on changed data using asynchronous methods

In my application, there is an icon that represents a favorite or not favorite status with either a red or white heart. The code snippet below shows how the image source changes based on the favorite status: <img :src="favoriteStatus ? '/icon ...

Running complex Firestore query within Cloud Functions

Currently, I am developing triggers that interact with a Firestore movie and user database. The main goal of one trigger is to present a new user with a list of top-rated movies in genres they have selected as their favorites. To achieve this, I store the ...